proxes 0.9.2 → 0.9.4

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/startup.sh CHANGED
@@ -4,14 +4,15 @@ set -e
4
4
  echo "DATABASE_URL: $DATABASE_URL"
5
5
  echo "ELASTICSEARCH_URL: $ELASTICSEARCH_URL"
6
6
  echo "APP_ROOT: $APP_ROOT"
7
+ bundle show ditty
8
+ bundle show proxes
7
9
 
8
10
  if [ "$1" = 'web-proxes' ]
9
11
  then
10
- cd /usr/src/app
12
+ cd $APP_ROOT
11
13
  bundle exec rake ditty:generate_tokens
12
14
  bundle exec rake ditty:migrate
13
15
  bundle exec rake ditty:seed
14
- crond
15
16
  exec bundle exec pumactl start "$@"
16
17
  fi
17
18
 
@@ -0,0 +1 @@
1
+ #react-dashboard{ 'data-elasticsearch-url' => '..'}
@@ -0,0 +1,60 @@
1
+ !!! 5
2
+ %html{ lang: 'en' }
3
+ %head
4
+ %meta{ charset: 'utf-8' }
5
+ %meta{ 'http-equiv' => 'X-UA-Compatible', 'content' => 'IE=edge,chrome=1' }
6
+ %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
7
+ %meta{ name: 'theme-color', content: '#ffffff' }
8
+ %link{ rel: 'manifest', href: '/_proxes/manifest.json' }
9
+ %link{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/_proxes/images/favicon-32x32.png' }
10
+ %link{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/_proxes/images/favicon-16x16.png' }
11
+ %link{ rel: 'apple-touch-icon', sizes: '76x76', href: '/_proxes/images/apple-icon.png' }
12
+ %link{ rel: 'mask-icon', href: '/_proxes/images/safari-pinned-tab.svg', color: '#5bbad5' }
13
+
14
+ %title
15
+ ProxES
16
+ - if defined? title
17
+ = "- #{title}"
18
+
19
+ %meta{ name: 'description', content: '' }
20
+ %meta{ name: 'author', content: '' }
21
+
22
+ / Le styles
23
+ %link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', media: 'screen' }
24
+ %link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/css/sb-admin-2.min.css', media: 'screen' }
25
+ %link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.css', media: 'screen' }
26
+ %link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', media: 'screen' }
27
+ /[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
28
+ /[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
29
+
30
+ %script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js' }
31
+ %script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/js/sb-admin-2.min.js' }
32
+ %script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.js' }
33
+ %body
34
+ #wrapper
35
+ = haml :'partials/navbar', locals: { title: (defined?(title) ? title : 'ProxES') }
36
+ #page-wrapper{ style: 'opacity: 0.8' }
37
+ .row
38
+ .col-md-12
39
+ -if defined? title
40
+ %h1.page-header= title
41
+ = haml :'partials/notifications'
42
+
43
+ = yield
44
+ %footer.footer.text-muted.text-center
45
+ %hr
46
+ .copyright
47
+ :plain
48
+ &copy; <script>document.write(new Date().getFullYear())</script>, DataTools.io
49
+
50
+
51
+ / Placed at the end of the document so the pages load faster
52
+ %script{ type: 'text/javascript', src: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' }
53
+ %script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.min.js' }
54
+ %script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.min.js' }
55
+ %script{ type: 'text/javascript', src: '/_proxes/js/bundle.js' }
56
+ :javascript
57
+ $(function() {
58
+ $('.sidebar-nav').metisMenu();
59
+ });
60
+
@@ -0,0 +1,25 @@
1
+ .navbar.navbar-default.navbar-static-top{ role: 'navigation', style: 'margin-bottom: 0' }
2
+ .navbar-header
3
+ %button.navbar-toggle.collapsed{ 'type' => 'button', 'data-toggle' => 'collapse', 'data-target' => '.navbar-collapse' }
4
+ %span.sr-only Toggle navigation
5
+ %span.icon-bar
6
+ %span.icon-bar
7
+ %span.icon-bar
8
+ %span.navbar-brand
9
+ %a{ href: "#{settings.map_path}" }
10
+ ProxES
11
+
12
+ -if authenticated?
13
+ %form.nav.navbar-top-links.navbar-form.navbar-right{ action: "#{settings.map_path}/auth/identity", method: 'post' }
14
+ %a.btn.btn-default{ href: "#{settings.map_path}/users/profile" } My Account
15
+ %input{ name: '_method', value: 'DELETE', type: 'hidden' }
16
+ %button.btn.btn-default{ type: 'submit' }
17
+ / %i.ti-panel
18
+ Logout
19
+ - else
20
+ %ul.nav.navbar-top-links.navbar-right
21
+ %li
22
+ %a.btn.btn-link{ href: "#{settings.map_path}/auth/identity" }
23
+ Log In
24
+ .navbar-default.sidebar{ role: 'navigation' }
25
+ = haml :'partials/sidebar'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proxes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jurgens du Toit
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-06 00:00:00.000000000 Z
11
+ date: 2018-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -457,6 +457,9 @@ files:
457
457
  - lib/proxes/forwarder.rb
458
458
  - lib/proxes/helpers/indices.rb
459
459
  - lib/proxes/loggers/elasticsearch.rb
460
+ - lib/proxes/middleware/error_handling.rb
461
+ - lib/proxes/middleware/metrics.rb
462
+ - lib/proxes/middleware/security.rb
460
463
  - lib/proxes/models/permission.rb
461
464
  - lib/proxes/policies/permission_policy.rb
462
465
  - lib/proxes/policies/request/bulk_policy.rb
@@ -478,7 +481,6 @@ files:
478
481
  - lib/proxes/request/search.rb
479
482
  - lib/proxes/request/snapshot.rb
480
483
  - lib/proxes/request/stats.rb
481
- - lib/proxes/security.rb
482
484
  - lib/proxes/services/es.rb
483
485
  - lib/proxes/version.rb
484
486
  - migrate/20170209_permissions.rb
@@ -499,6 +501,9 @@ files:
499
501
  - public/manifest.json
500
502
  - src/scripts/app.js
501
503
  - startup.sh
504
+ - views/index.haml
505
+ - views/layout.haml
506
+ - views/partials/navbar.haml
502
507
  - views/permissions/display.haml
503
508
  - views/permissions/edit.haml
504
509
  - views/permissions/form.haml
@@ -525,7 +530,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
525
530
  version: '0'
526
531
  requirements: []
527
532
  rubyforge_project:
528
- rubygems_version: 2.7.5
533
+ rubygems_version: 2.7.6
529
534
  signing_key:
530
535
  specification_version: 4
531
536
  summary: Rack wrapper around Elasticsearch to provide security and management features
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'proxes/request'
4
- require 'proxes/policies/request_policy'
5
- require 'ditty/services/logger'
6
- require 'ditty/helpers/pundit'
7
- require 'ditty/helpers/authentication'
8
- require 'ditty/helpers/wisper'
9
-
10
- module ProxES
11
- class Security
12
- attr_reader :env, :logger
13
-
14
- include Ditty::Helpers::Authentication
15
- include Ditty::Helpers::Pundit
16
- include Ditty::Helpers::Wisper
17
- include Wisper::Publisher
18
-
19
- def initialize(app, logger = nil)
20
- @app = app
21
- @logger = logger || ::Ditty::Services::Logger.instance
22
- end
23
-
24
- def error(message, code = 500)
25
- headers = { 'Content-Type' => 'application/json' }
26
- headers['WWW-Authenticate'] = 'Basic realm="security"' if code == 401
27
- [code, headers, ['{"error":"' + message + '"}']]
28
- end
29
-
30
- def redirect(destination, code = 302)
31
- [code, { 'Location' => destination}, []]
32
- end
33
-
34
- def check(request)
35
- check_basic request
36
- authorize request, request.request_method.downcase
37
- rescue Pundit::NotAuthorizedError
38
- return redirect '/_proxes/' if request.get_header('HTTP_ACCEPT') && request.get_header('HTTP_ACCEPT').include?('text/html')
39
-
40
- log_action(:es_request_denied, details: "#{request.request_method.upcase} #{request.fullpath} (#{request.class.name})")
41
- logger.debug "Access denied for #{current_user ? current_user.email : 'Anonymous User'} by security layer: #{request.request_method.upcase} #{request.fullpath} (#{request.class.name})"
42
- error 'Not Authorized', 401
43
- rescue ::Ditty::Helpers::NotAuthenticated
44
- logger.warn "Access denied for unauthenticated request by security layer: #{request.request_method.upcase} #{request.fullpath} (#{request.class.name})"
45
- error 'Not Authenticated', 401
46
- rescue StandardError => e
47
- raise e if env['RACK_ENV'] != 'production'
48
- logger.error "Access denied for #{current_user ? current_user.email : 'Anonymous User'} by security exception: #{request.request_method.upcase} #{request.fullpath} (#{request.class.name})"
49
- logger.error e
50
- error 'Forbidden', 403
51
- end
52
-
53
- def forward(request)
54
- start = Time.now.to_f
55
- result = @app.call request.env
56
- broadcast(:call_completed, request, Time.now.to_f - start) if result[0].to_i >= 200 && result[0].to_i < 300
57
- result
58
- rescue Errno::EHOSTUNREACH
59
- error 'Could not reach Elasticsearch at ' + ENV['ELASTICSEARCH_URL']
60
- rescue Errno::ECONNREFUSED
61
- error 'Elasticsearch not listening at ' + ENV['ELASTICSEARCH_URL']
62
- end
63
-
64
- def log(request, stage)
65
- logger.debug '============' + stage.ljust(56) + '============'
66
- logger.debug '= ' + "Request: #{request.request_method} #{request.fullpath} (#{request.class.name})".ljust(76) + ' ='
67
- logger.debug '= ' + "Endpoint: #{request.endpoint}".ljust(76) + ' ='
68
- logger.debug '================================================================================'
69
- end
70
-
71
- def call(env)
72
- @env = env
73
-
74
- request = Request.from_env(env)
75
- broadcast(:call_started, request)
76
-
77
- log(request, 'BEFORE')
78
- unless env['PROXES_PASSTHROUGH']
79
- result = check(request)
80
- return result if result.is_a?(Array) # Rack Response
81
-
82
- request.index = policy_scope(request) if request.indices?
83
- log(request, 'AFTER')
84
- end
85
-
86
- forward request
87
- end
88
- end
89
- end