putsreq 0.0.1
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 +7 -0
- data/.codeclimate.yml +7 -0
- data/.coffeelint.json +5 -0
- data/.gitignore +20 -0
- data/.hound.yml +14 -0
- data/.jshintrc +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +110 -0
- data/.ruby-version +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +91 -0
- data/Gemfile.lock +270 -0
- data/LICENSE +5 -0
- data/Procfile +1 -0
- data/README.md +147 -0
- data/Rakefile +8 -0
- data/app/assets/javascripts/application.js +27 -0
- data/app/assets/javascripts/buckets.js.coffee +68 -0
- data/app/assets/javascripts/initializers.js.coffee +8 -0
- data/app/assets/stylesheets/application.css +15 -0
- data/app/assets/stylesheets/base.css +68 -0
- data/app/assets/stylesheets/buckets.css.scss +91 -0
- data/app/assets/stylesheets/helpers.css +154 -0
- data/app/controllers/application_controller.rb +35 -0
- data/app/controllers/buckets_controller.rb +88 -0
- data/app/controllers/concerns/.keep +0 -0
- data/app/controllers/home_controller.rb +18 -0
- data/app/helpers/application_helper.rb +14 -0
- data/app/interactors/create_request.rb +15 -0
- data/app/interactors/create_response.rb +11 -0
- data/app/interactors/eval_response_builder.rb +55 -0
- data/app/interactors/filter_headers.rb +28 -0
- data/app/interactors/forward_request.rb +39 -0
- data/app/interactors/notify_count.rb +15 -0
- data/app/interactors/record_request.rb +5 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/models/bucket.rb +99 -0
- data/app/models/concerns/.keep +0 -0
- data/app/models/request.rb +36 -0
- data/app/models/response.rb +22 -0
- data/app/models/user.rb +42 -0
- data/app/views/buckets/_buttons.html.erb +4 -0
- data/app/views/buckets/_form.html.erb +33 -0
- data/app/views/buckets/_readonly_buttons.html.erb +1 -0
- data/app/views/buckets/_requests.html.erb +45 -0
- data/app/views/buckets/show.html.erb +58 -0
- data/app/views/home/index.html.erb +45 -0
- data/app/views/layouts/_header.html.erb +18 -0
- data/app/views/layouts/application.html.erb +28 -0
- data/app/views/layouts/devise.html.erb +22 -0
- data/app/views/shared/_flash.html.erb +10 -0
- data/app/views/users/confirmations/new.html.erb +12 -0
- data/app/views/users/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/users/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/users/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/users/passwords/edit.html.erb +32 -0
- data/app/views/users/passwords/new.html.erb +23 -0
- data/app/views/users/registrations/edit.html.erb +59 -0
- data/app/views/users/registrations/new.html.erb +46 -0
- data/app/views/users/sessions/new.html.erb +38 -0
- data/app/views/users/shared/_links.erb +25 -0
- data/app/views/users/unlocks/new.html.erb +12 -0
- data/bin/bundle +3 -0
- data/bin/putsreq +71 -0
- data/bin/rails +4 -0
- data/bin/rake +4 -0
- data/bin/rspec +16 -0
- data/config.ru +4 -0
- data/config/application.rb +42 -0
- data/config/boot.rb +4 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +33 -0
- data/config/environments/production.rb +82 -0
- data/config/environments/test.rb +36 -0
- data/config/initializers/backtrace_silencers.rb +7 -0
- data/config/initializers/devise.rb +256 -0
- data/config/initializers/filter_parameter_logging.rb +4 -0
- data/config/initializers/inflections.rb +16 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/initializers/redis.rb +17 -0
- data/config/initializers/secret_token.rb +12 -0
- data/config/initializers/session_store.rb +3 -0
- data/config/initializers/setup_email.rb +10 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/locales/devise.en.yml +59 -0
- data/config/locales/en.yml +23 -0
- data/config/mongoid.yml +47 -0
- data/config/routes.rb +15 -0
- data/config/unicorn.rb +16 -0
- data/lib/assets/.keep +0 -0
- data/lib/putsreq/version.rb +3 -0
- data/lib/tasks/.keep +0 -0
- data/public/404.html +58 -0
- data/public/422.html +58 -0
- data/public/500.html +57 -0
- data/public/favicon.ico +0 -0
- data/public/images/.keep +0 -0
- data/public/images/favicon.png +0 -0
- data/public/images/favicon144.png +0 -0
- data/public/images/favicon152.png +0 -0
- data/public/images/glyphicons-halflings-white.png +0 -0
- data/public/images/glyphicons-halflings.png +0 -0
- data/public/images/logo.png +0 -0
- data/public/javascripts/vendor/ace/theme-monokai.js +1 -0
- data/public/javascripts/vendor/ace/theme-textmate.js +1 -0
- data/public/javascripts/vendor/ace/worker-javascript.js +1 -0
- data/public/javascripts/vendor/ace/worker-json.js +1 -0
- data/public/robots.txt +5 -0
- data/putsreq.gemspec +22 -0
- data/spec/controllers/buckets_controller_spec.rb +164 -0
- data/spec/interactors/create_request_spec.rb +34 -0
- data/spec/interactors/create_response_spec.rb +14 -0
- data/spec/interactors/eval_response_builder_spec.rb +63 -0
- data/spec/interactors/forward_request_spec.rb +39 -0
- data/spec/models/bucket_spec.rb +96 -0
- data/spec/models/user_spec.rb +5 -0
- data/spec/spec_helper.rb +66 -0
- data/vendor/assets/javascripts/.keep +0 -0
- data/vendor/assets/javascripts/ace/ace.js +10 -0
- data/vendor/assets/javascripts/ace/ext-searchbox.js +1 -0
- data/vendor/assets/javascripts/ace/ext-spellcheck.js +1 -0
- data/vendor/assets/javascripts/ace/ext-static_highlight.js +1 -0
- data/vendor/assets/javascripts/ace/ext-textarea.js +1 -0
- data/vendor/assets/javascripts/ace/keybinding-emacs.js +1 -0
- data/vendor/assets/javascripts/ace/keybinding-vim.js +1 -0
- data/vendor/assets/javascripts/ace/mode-abap.js +1 -0
- data/vendor/assets/javascripts/ace/mode-asciidoc.js +1 -0
- data/vendor/assets/javascripts/ace/mode-c9search.js +1 -0
- data/vendor/assets/javascripts/ace/mode-c_cpp.js +1 -0
- data/vendor/assets/javascripts/ace/mode-clojure.js +1 -0
- data/vendor/assets/javascripts/ace/mode-coffee.js +1 -0
- data/vendor/assets/javascripts/ace/mode-coldfusion.js +1 -0
- data/vendor/assets/javascripts/ace/mode-csharp.js +1 -0
- data/vendor/assets/javascripts/ace/mode-css.js +1 -0
- data/vendor/assets/javascripts/ace/mode-curly.js +1 -0
- data/vendor/assets/javascripts/ace/mode-dart.js +1 -0
- data/vendor/assets/javascripts/ace/mode-diff.js +1 -0
- data/vendor/assets/javascripts/ace/mode-django.js +1 -0
- data/vendor/assets/javascripts/ace/mode-dot.js +1 -0
- data/vendor/assets/javascripts/ace/mode-glsl.js +1 -0
- data/vendor/assets/javascripts/ace/mode-golang.js +1 -0
- data/vendor/assets/javascripts/ace/mode-groovy.js +1 -0
- data/vendor/assets/javascripts/ace/mode-haml.js +1 -0
- data/vendor/assets/javascripts/ace/mode-haxe.js +1 -0
- data/vendor/assets/javascripts/ace/mode-html.js +1 -0
- data/vendor/assets/javascripts/ace/mode-jade.js +1 -0
- data/vendor/assets/javascripts/ace/mode-java.js +1 -0
- data/vendor/assets/javascripts/ace/mode-javascript.js +1 -0
- data/vendor/assets/javascripts/ace/mode-json.js +1 -0
- data/vendor/assets/javascripts/ace/mode-jsp.js +1 -0
- data/vendor/assets/javascripts/ace/mode-jsx.js +1 -0
- data/vendor/assets/javascripts/ace/mode-latex.js +1 -0
- data/vendor/assets/javascripts/ace/mode-less.js +1 -0
- data/vendor/assets/javascripts/ace/mode-liquid.js +1 -0
- data/vendor/assets/javascripts/ace/mode-lisp.js +1 -0
- data/vendor/assets/javascripts/ace/mode-livescript.js +1 -0
- data/vendor/assets/javascripts/ace/mode-lua.js +1 -0
- data/vendor/assets/javascripts/ace/mode-luapage.js +1 -0
- data/vendor/assets/javascripts/ace/mode-lucene.js +1 -0
- data/vendor/assets/javascripts/ace/mode-makefile.js +1 -0
- data/vendor/assets/javascripts/ace/mode-markdown.js +1 -0
- data/vendor/assets/javascripts/ace/mode-objectivec.js +1 -0
- data/vendor/assets/javascripts/ace/mode-ocaml.js +1 -0
- data/vendor/assets/javascripts/ace/mode-perl.js +1 -0
- data/vendor/assets/javascripts/ace/mode-pgsql.js +1 -0
- data/vendor/assets/javascripts/ace/mode-php.js +1 -0
- data/vendor/assets/javascripts/ace/mode-powershell.js +1 -0
- data/vendor/assets/javascripts/ace/mode-python.js +1 -0
- data/vendor/assets/javascripts/ace/mode-r.js +1 -0
- data/vendor/assets/javascripts/ace/mode-rdoc.js +1 -0
- data/vendor/assets/javascripts/ace/mode-rhtml.js +1 -0
- data/vendor/assets/javascripts/ace/mode-ruby.js +1 -0
- data/vendor/assets/javascripts/ace/mode-scad.js +1 -0
- data/vendor/assets/javascripts/ace/mode-scala.js +1 -0
- data/vendor/assets/javascripts/ace/mode-scheme.js +1 -0
- data/vendor/assets/javascripts/ace/mode-scss.js +1 -0
- data/vendor/assets/javascripts/ace/mode-sh.js +1 -0
- data/vendor/assets/javascripts/ace/mode-sql.js +1 -0
- data/vendor/assets/javascripts/ace/mode-stylus.js +1 -0
- data/vendor/assets/javascripts/ace/mode-svg.js +1 -0
- data/vendor/assets/javascripts/ace/mode-tcl.js +1 -0
- data/vendor/assets/javascripts/ace/mode-tex.js +1 -0
- data/vendor/assets/javascripts/ace/mode-text.js +0 -0
- data/vendor/assets/javascripts/ace/mode-textile.js +1 -0
- data/vendor/assets/javascripts/ace/mode-tm_snippet.js +1 -0
- data/vendor/assets/javascripts/ace/mode-typescript.js +1 -0
- data/vendor/assets/javascripts/ace/mode-vbscript.js +1 -0
- data/vendor/assets/javascripts/ace/mode-xml.js +1 -0
- data/vendor/assets/javascripts/ace/mode-xquery.js +1 -0
- data/vendor/assets/javascripts/ace/mode-yaml.js +1 -0
- data/vendor/assets/javascripts/ace/theme-ambiance.js +1 -0
- data/vendor/assets/javascripts/ace/theme-chaos.js +1 -0
- data/vendor/assets/javascripts/ace/theme-chrome.js +1 -0
- data/vendor/assets/javascripts/ace/theme-clouds.js +1 -0
- data/vendor/assets/javascripts/ace/theme-clouds_midnight.js +1 -0
- data/vendor/assets/javascripts/ace/theme-cobalt.js +1 -0
- data/vendor/assets/javascripts/ace/theme-crimson_editor.js +1 -0
- data/vendor/assets/javascripts/ace/theme-dawn.js +1 -0
- data/vendor/assets/javascripts/ace/theme-dreamweaver.js +1 -0
- data/vendor/assets/javascripts/ace/theme-eclipse.js +1 -0
- data/vendor/assets/javascripts/ace/theme-github.js +1 -0
- data/vendor/assets/javascripts/ace/theme-idle_fingers.js +1 -0
- data/vendor/assets/javascripts/ace/theme-kr.js +1 -0
- data/vendor/assets/javascripts/ace/theme-merbivore.js +1 -0
- data/vendor/assets/javascripts/ace/theme-merbivore_soft.js +1 -0
- data/vendor/assets/javascripts/ace/theme-mono_industrial.js +1 -0
- data/vendor/assets/javascripts/ace/theme-monokai.js +1 -0
- data/vendor/assets/javascripts/ace/theme-pastel_on_dark.js +1 -0
- data/vendor/assets/javascripts/ace/theme-solarized_dark.js +1 -0
- data/vendor/assets/javascripts/ace/theme-solarized_light.js +1 -0
- data/vendor/assets/javascripts/ace/theme-textmate.js +1 -0
- data/vendor/assets/javascripts/ace/theme-tomorrow.js +1 -0
- data/vendor/assets/javascripts/ace/theme-tomorrow_night.js +1 -0
- data/vendor/assets/javascripts/ace/theme-tomorrow_night_blue.js +1 -0
- data/vendor/assets/javascripts/ace/theme-tomorrow_night_bright.js +1 -0
- data/vendor/assets/javascripts/ace/theme-tomorrow_night_eighties.js +1 -0
- data/vendor/assets/javascripts/ace/theme-twilight.js +1 -0
- data/vendor/assets/javascripts/ace/theme-vibrant_ink.js +1 -0
- data/vendor/assets/javascripts/ace/theme-xcode.js +1 -0
- data/vendor/assets/javascripts/ace/worker-coffee.js +1 -0
- data/vendor/assets/javascripts/ace/worker-css.js +1 -0
- data/vendor/assets/javascripts/ace/worker-javascript.js +1 -0
- data/vendor/assets/javascripts/ace/worker-json.js +1 -0
- data/vendor/assets/javascripts/ace/worker-php.js +1 -0
- data/vendor/assets/javascripts/ace/worker-xquery.js +1 -0
- data/vendor/assets/javascripts/jquery.tipsy.js +198 -0
- data/vendor/assets/javascripts/mode-javascript.js +1 -0
- data/vendor/assets/javascripts/theme-monokai.js +1 -0
- data/vendor/assets/javascripts/worker-javascript.js +1 -0
- data/vendor/assets/stylesheets/.keep +0 -0
- data/vendor/assets/stylesheets/tipsy.css +25 -0
- metadata +311 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
.bg {background:#000 !important}
|
2
|
+
.block {display:block !important}
|
3
|
+
.border {border:1px solid black !important}
|
4
|
+
.breadcrumb {font-size:11px !important}
|
5
|
+
.bz {border: 0 !important}
|
6
|
+
.f9 {font-size:57px !important;}
|
7
|
+
.f8 {font-size:38px !important;}
|
8
|
+
.f7 {font-size:30px !important;}
|
9
|
+
.f6 {font-size:27px !important;}
|
10
|
+
.f5 {font-size:20px !important;}
|
11
|
+
.f4 {font-size:17px !important;}
|
12
|
+
.f3 {font-size:15px !important;}
|
13
|
+
.f2 {font-size:13px !important;}
|
14
|
+
.f1 {font-size:8px !important;}
|
15
|
+
.f10 {font-size:10px !important;}
|
16
|
+
.fw {width:100% !important}
|
17
|
+
.fwb {font-weight:bold !important}
|
18
|
+
.fsi {font-style:italic !important}
|
19
|
+
.fl {float:left !important}
|
20
|
+
.fr {float:right !important}
|
21
|
+
.h10 {height:10px !important}
|
22
|
+
.h20 {height:20px !important}
|
23
|
+
.h30 {height:30px !important}
|
24
|
+
.h40 {height:40px !important}
|
25
|
+
.h50 {height:50px !important}
|
26
|
+
.h80 {height:80px !important}
|
27
|
+
.h100 {height:100px !important}
|
28
|
+
.h150 {height:150px !important}
|
29
|
+
.h200 {height:200px !important}
|
30
|
+
.h250 {height:250px !important}
|
31
|
+
.h300 {height:300px !important}
|
32
|
+
.hidden {display: none !important}
|
33
|
+
.hr {border-top: 1px solid #c9c9c9;}
|
34
|
+
.left {float:left}
|
35
|
+
.lh5 {line-height:5px !important}
|
36
|
+
.lh10 {line-height:10px !important}
|
37
|
+
.lh15 {line-height:15px !important}
|
38
|
+
.lh20 {line-height:20px !important}
|
39
|
+
.lh25 {line-height:25px !important}
|
40
|
+
.lh30 {line-height:30px !important}
|
41
|
+
.lh35 {line-height:35px !important}
|
42
|
+
.lm0 {margin-left:0 !important}
|
43
|
+
.no-text-shadow {text-shadow: none;}
|
44
|
+
.p5 {padding: 5px !important;}
|
45
|
+
.right {float:right}
|
46
|
+
.tac {text-align:center !important}
|
47
|
+
.tal {text-align:left !important}
|
48
|
+
.tar {text-align:right !important}
|
49
|
+
.tm1 {margin-top:1px !important}
|
50
|
+
.tm2 {margin-top:2px !important}
|
51
|
+
.tm3 {margin-top:3px !important}
|
52
|
+
.tm4 {margin-top:4px !important}
|
53
|
+
.tm5 {margin-top:5px !important}
|
54
|
+
.tm6 {margin-top:6px !important}
|
55
|
+
.tm7 {margin-top:7px !important}
|
56
|
+
.tm8 {margin-top:8px !important}
|
57
|
+
.tm9 {margin-top:9px !important}
|
58
|
+
.tm10 {margin-top:10px !important}
|
59
|
+
.tm11 {margin-top:11px !important}
|
60
|
+
.tm12 {margin-top:12px !important}
|
61
|
+
.tm13 {margin-top:13px !important}
|
62
|
+
.tm14 {margin-top:14px !important}
|
63
|
+
.tm15 {margin-top:15px !important}
|
64
|
+
.tm20 {margin-top:20px !important}
|
65
|
+
.tm25 {margin-top:25px !important}
|
66
|
+
.tm30 {margin-top:30px !important}
|
67
|
+
.tm35 {margin-top:35px !important}
|
68
|
+
.tm40 {margin-top:40px !important}
|
69
|
+
.tm45 {margin-top:45px !important}
|
70
|
+
.tm50 {margin-top:50px !important}
|
71
|
+
.tm60 {margin-top:60px !important}
|
72
|
+
.tm70 {margin-top:70px !important}
|
73
|
+
.tm80 {margin-top:80px !important}
|
74
|
+
.tm90 {margin-top:90px !important}
|
75
|
+
.tm100 {margin-top:100px !important}
|
76
|
+
.tm130 {margin-top:130px !important}
|
77
|
+
.bm0 {margin-bottom:0 !important}
|
78
|
+
.bm5 {margin-bottom:5px !important}
|
79
|
+
.bm10 {margin-bottom:10px !important}
|
80
|
+
.bm15 {margin-bottom:15px !important}
|
81
|
+
.bm20 {margin-bottom:20px !important}
|
82
|
+
.bm25 {margin-bottom:25px !important}
|
83
|
+
.bm30 {margin-bottom:30px !important}
|
84
|
+
.bm35 {margin-bottom:35px !important}
|
85
|
+
.bm40 {margin-bottom:40px !important}
|
86
|
+
.bm45 {margin-bottom:45px !important}
|
87
|
+
.bm50 {margin-bottom:50px !important}
|
88
|
+
.pt1 {padding-top:1px !important}
|
89
|
+
.pt2 {padding-top:2px !important}
|
90
|
+
.pt3 {padding-top:3px !important}
|
91
|
+
.pt4 {padding-top:4px !important}
|
92
|
+
.pt5 {padding-top:5px !important}
|
93
|
+
.pt10 {padding-top:10px !important}
|
94
|
+
.pt20 {padding-top:20px !important}
|
95
|
+
.pt30 {padding-top:30px !important}
|
96
|
+
.pb1 {padding-bottom:1px !important}
|
97
|
+
.pb2 {padding-bottom:2px !important}
|
98
|
+
.pb3 {padding-bottom:3px !important}
|
99
|
+
.pb4 {padding-bottom:4px !important}
|
100
|
+
.pb5 {padding-bottom:5px !important}
|
101
|
+
.pb10 {padding-bottom:10px !important}
|
102
|
+
.pb20 {padding-bottom:20px !important}
|
103
|
+
.pb30 {padding-bottom:30px !important}
|
104
|
+
.pl10 {padding-left:10px !important}
|
105
|
+
.pl20 {padding-left:20px !important}
|
106
|
+
.pl30 {padding-left:30px !important}
|
107
|
+
.pr10 {padding-right:10px !important}
|
108
|
+
.pr20 {padding-right:20px !important}
|
109
|
+
.pr30 {padding-right:30px !important}
|
110
|
+
.lm1 {margin-left:1px !important}
|
111
|
+
.lm2 {margin-left:2px !important}
|
112
|
+
.lm3 {margin-left:3px !important}
|
113
|
+
.lm4 {margin-left:4px !important}
|
114
|
+
.lm5 {margin-left:5px !important}
|
115
|
+
.lm10 {margin-left:10px !important}
|
116
|
+
.lm15 {margin-left:15px !important}
|
117
|
+
.lm20 {margin-left:20px !important}
|
118
|
+
.lm25 {margin-left:25px !important}
|
119
|
+
.lm30 {margin-left:30px !important}
|
120
|
+
.lm35 {margin-left:35px !important}
|
121
|
+
.lm40 {margin-left:40px !important}
|
122
|
+
.lm45 {margin-left:45px !important}
|
123
|
+
.lm50 {margin-left:50px !important}
|
124
|
+
.pointer {cursor: pointer !important}
|
125
|
+
.rm1 {margin-right:1px !important}
|
126
|
+
.rm2 {margin-right:2px !important}
|
127
|
+
.rm3 {margin-right:3px !important}
|
128
|
+
.rm4 {margin-right:4px !important}
|
129
|
+
.rm5 {margin-right:5px !important}
|
130
|
+
.rm10 {margin-right:10px !important}
|
131
|
+
.rm15 {margin-right:15px !important}
|
132
|
+
.rm20 {margin-right:20px !important}
|
133
|
+
.rm25 {margin-right:25px !important}
|
134
|
+
.rm30 {margin-right:30px !important}
|
135
|
+
.rm35 {margin-right:35px !important}
|
136
|
+
.rm40 {margin-right:40px !important}
|
137
|
+
.rm45 {margin-right:45px !important}
|
138
|
+
.rm50 {margin-right:50px !important}
|
139
|
+
.w100 {width:100px !important}
|
140
|
+
.w200 {width:200px !important}
|
141
|
+
.w300 {width:300px !important}
|
142
|
+
.w400 {width:400px !important}
|
143
|
+
.w500 {width:500px !important}
|
144
|
+
.w5pc {width:5% !important;}
|
145
|
+
.w10pc {width:10% !important;}
|
146
|
+
.w20pc {width:10% !important;}
|
147
|
+
.w30pc {width:30% !important;}
|
148
|
+
.w40pc {width:40% !important;}
|
149
|
+
.w50pc {width:50% !important;}
|
150
|
+
.w60pc {width:60% !important;}
|
151
|
+
.w70pc {width:70% !important;}
|
152
|
+
.w80pc {width:80% !important;}
|
153
|
+
.w90pc {width:90% !important;}
|
154
|
+
.w100pc {width:100% !important;}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
# Prevent CSRF attacks by raising an exception.
|
3
|
+
# For APIs, you may want to use :null_session instead.
|
4
|
+
protect_from_forgery with: :exception
|
5
|
+
|
6
|
+
helper_method :is_owner?
|
7
|
+
|
8
|
+
before_action :configure_permitted_parameters, if: :devise_controller?
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def check_ownership!
|
13
|
+
unless is_owner?(bucket)
|
14
|
+
redirect_to bucket_path(bucket.token), alert: 'Only the bucket owner can perform this operation'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_owner?(bucket)
|
19
|
+
owner_token == bucket.owner_token || (user_signed_in? && bucket.user == current_user)
|
20
|
+
end
|
21
|
+
|
22
|
+
def owner_token
|
23
|
+
cookies[:owner_token] ||= { value: SecureRandom.hex(24), expires: 1.year.from_now }
|
24
|
+
end
|
25
|
+
|
26
|
+
def bucket
|
27
|
+
@bucket ||= Bucket.find_by(token: params[:token])
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_permitted_parameters
|
31
|
+
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password, :password_confirmation, :remember_me) }
|
32
|
+
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:name, :email, :password, :remember_me) }
|
33
|
+
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :email, :password, :password_confirmation, :current_password) }
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class BucketsController < ApplicationController
|
2
|
+
skip_before_action :verify_authenticity_token, only: :record
|
3
|
+
|
4
|
+
before_filter :check_ownership!, only: %i[clear destroy update]
|
5
|
+
|
6
|
+
def create
|
7
|
+
new_bucket = { owner_token: owner_token }
|
8
|
+
new_bucket[:user_id] = current_user.id if user_signed_in?
|
9
|
+
|
10
|
+
bucket = Bucket.create(new_bucket)
|
11
|
+
|
12
|
+
redirect_to bucket_path(bucket.token)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fork
|
16
|
+
forked_bucket = Bucket.create(owner_token: owner_token,
|
17
|
+
response_builder: bucket.response_builder,
|
18
|
+
name: "Copy of #{bucket.name}",
|
19
|
+
fork: bucket)
|
20
|
+
|
21
|
+
redirect_to bucket_path(forked_bucket.token)
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear
|
25
|
+
bucket.clear_history
|
26
|
+
|
27
|
+
redirect_to bucket_path(bucket.token)
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
bucket.destroy
|
32
|
+
|
33
|
+
redirect_to root_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
@requests = bucket.requests.page(params[:page]).per 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
update_bucket = bucket_params
|
42
|
+
update_bucket[:user_id] = current_user.id if user_signed_in?
|
43
|
+
|
44
|
+
bucket.update_attributes update_bucket
|
45
|
+
|
46
|
+
redirect_to bucket_path(bucket.token)
|
47
|
+
end
|
48
|
+
|
49
|
+
def last
|
50
|
+
return render_request_not_found unless last_request = bucket.last_request
|
51
|
+
|
52
|
+
respond_to do |format|
|
53
|
+
format.html { render text: last_request.body }
|
54
|
+
format.json { render json: JSON.pretty_generate(last_request.attributes) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def last_response
|
59
|
+
return render_request_not_found unless last_response = bucket.last_response
|
60
|
+
|
61
|
+
respond_to do |format|
|
62
|
+
format.html { render text: last_response.body }
|
63
|
+
format.json { render json: JSON.pretty_generate(last_response.attributes) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def record
|
68
|
+
result = RecordRequest.call(bucket: bucket, rack_request: request)
|
69
|
+
recorded_response = result.response
|
70
|
+
|
71
|
+
response.headers.merge! recorded_response.headers.to_h
|
72
|
+
|
73
|
+
render text: recorded_response.body_as_string, status: recorded_response.status
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def render_request_not_found
|
79
|
+
respond_to do |format|
|
80
|
+
format.html { redirect_to bucket_path(bucket.token), alert: 'Please submit a request first' }
|
81
|
+
format.json { render nothing: true, status: 404 }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def bucket_params
|
86
|
+
params.require(:bucket).permit(:response_builder, :name)
|
87
|
+
end
|
88
|
+
end
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class HomeController < ApplicationController
|
2
|
+
def index
|
3
|
+
if user_signed_in?
|
4
|
+
selector = Bucket.or([user: current_user], [owner_token: owner_token])
|
5
|
+
else
|
6
|
+
selector = Bucket.where(owner_token: owner_token)
|
7
|
+
end
|
8
|
+
|
9
|
+
@buckets = selector.order(:created_at.desc).limit(20)
|
10
|
+
|
11
|
+
@buckets.each do |bucket|
|
12
|
+
next if !user_signed_in? || bucket.user
|
13
|
+
|
14
|
+
# assign buckets created without login to the current logged user
|
15
|
+
bucket.update_attribute :user, current_user
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ApplicationHelper
|
2
|
+
def dispatcher_route
|
3
|
+
controller_name = controller_path.gsub(/\//, "_")
|
4
|
+
"#{controller_name}##{action_name}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def token_url(token)
|
8
|
+
"#{request.protocol}#{request.host_with_port}/#{token}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def show_no_requests_found(bucket)
|
12
|
+
content_tag(:p, 'No requests found.')
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateRequest
|
2
|
+
include Interactor
|
3
|
+
|
4
|
+
delegate :bucket, :rack_request, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
context.request = bucket.requests.create(body: rack_request.body.read,
|
8
|
+
content_length: rack_request.content_length,
|
9
|
+
request_method: rack_request.request_method,
|
10
|
+
ip: rack_request.ip,
|
11
|
+
url: rack_request.url,
|
12
|
+
headers: FilterHeaders.call(headers: rack_request.env).headers,
|
13
|
+
params: rack_request.request_parameters)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class EvalResponseBuilder
|
2
|
+
include Interactor
|
3
|
+
|
4
|
+
delegate :request, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
v8_ctx = V8::Context.new timeout: timeout
|
8
|
+
|
9
|
+
eval_response_builder(v8_ctx)
|
10
|
+
|
11
|
+
eval_request(v8_ctx)
|
12
|
+
|
13
|
+
eval_response(v8_ctx)
|
14
|
+
rescue => e
|
15
|
+
context.built_response = { 'status' => 500,
|
16
|
+
'headers' => { 'Content-Type' => 'text/plain' },
|
17
|
+
'body' => e.message }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def eval_request(v8_ctx)
|
23
|
+
context.built_request = JSON.parse(v8_ctx.eval('JSON.stringify(request)'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def eval_response(v8_ctx)
|
27
|
+
context.built_response = v8_ctx.eval('JSON.stringify(response)')
|
28
|
+
|
29
|
+
# filter allowed parameters
|
30
|
+
context.built_response = JSON.parse(context.built_response).select do |key, value|
|
31
|
+
%w(status headers body).include?(key) && value.to_s.present?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_response_builder_attrs(v8_ctx)
|
36
|
+
v8_ctx['response'] = { 'status' => 200,
|
37
|
+
'headers' => {},
|
38
|
+
'body' => 'ok' }
|
39
|
+
|
40
|
+
v8_ctx['request'] = { 'request_method' => request.request_method,
|
41
|
+
'body' => request.body,
|
42
|
+
'params' => request.params,
|
43
|
+
'headers' => request.headers }
|
44
|
+
end
|
45
|
+
|
46
|
+
def eval_response_builder(v8_ctx)
|
47
|
+
initialize_response_builder_attrs(v8_ctx)
|
48
|
+
|
49
|
+
v8_ctx.eval(context.bucket.response_builder.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
def timeout
|
53
|
+
context.timeout ||= 2500
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class FilterHeaders
|
2
|
+
include Interactor
|
3
|
+
|
4
|
+
BLACKLIST_HEADERS = %w(HOST CF X-REQUEST X-FORWARDED CONNECT-TIME TOTAL-ROUTE-TIME VIA).freeze
|
5
|
+
WHITELIST_HEADERS = %w(HTTP_ CONTENT).freeze
|
6
|
+
|
7
|
+
delegate :headers, to: :context
|
8
|
+
|
9
|
+
def call
|
10
|
+
context.headers = client_supplied_headers
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def client_supplied_headers
|
16
|
+
headers.to_h.each_with_object({}) do |(key, value), h|
|
17
|
+
next unless value.to_s.present?
|
18
|
+
|
19
|
+
next unless key.upcase.start_with?(*WHITELIST_HEADERS)
|
20
|
+
|
21
|
+
key = key.sub('HTTP_', '').tr('_', '-')
|
22
|
+
|
23
|
+
next if key.upcase.start_with?(*BLACKLIST_HEADERS)
|
24
|
+
|
25
|
+
h[key] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class ForwardRequest
|
2
|
+
include Interactor
|
3
|
+
|
4
|
+
delegate :built_request, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
return unless forward_url = built_request.try(:[], 'forwardTo')
|
8
|
+
|
9
|
+
# use the response from the forwarded URL
|
10
|
+
context.built_response = forward_to(built_request, forward_url)
|
11
|
+
rescue => e
|
12
|
+
context.built_response = { 'status' => 500,
|
13
|
+
'headers' => { 'Content-Type' => 'text/plain' },
|
14
|
+
'body' => e.message }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def forward_to(built_request, forward_url)
|
20
|
+
|
21
|
+
options = { timeout: 5,
|
22
|
+
headers: built_request['headers'],
|
23
|
+
body: body }
|
24
|
+
|
25
|
+
forwarded_response = HTTParty.send(built_request['request_method'].downcase.to_sym, forward_url, options)
|
26
|
+
|
27
|
+
{ 'status' => forwarded_response.code,
|
28
|
+
'headers' => FilterHeaders.call(headers: forwarded_response.headers).headers,
|
29
|
+
'body' => forwarded_response.body }
|
30
|
+
end
|
31
|
+
|
32
|
+
def body
|
33
|
+
if built_request['body'].is_a?(Hash)
|
34
|
+
JSON.dump(built_request['body'])
|
35
|
+
else
|
36
|
+
built_request['body'].to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|