proxes 0.1.0
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 +24 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +12 -0
- data/.ruby-version +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +4 -0
- data/Gemfile.ci +15 -0
- data/Gemfile.dev +10 -0
- data/Gemfile.dev.lock +155 -0
- data/LICENSE.txt +8 -0
- data/README.md +83 -0
- data/Rakefile +9 -0
- data/Vagrantfile +46 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/config.ru +64 -0
- data/config/logger.yml +3 -0
- data/gulpfile.js +80 -0
- data/lib/proxes.rb +3 -0
- data/lib/proxes/app.rb +48 -0
- data/lib/proxes/controllers/application.rb +53 -0
- data/lib/proxes/controllers/audit_logs.rb +34 -0
- data/lib/proxes/controllers/auth_identity.rb +21 -0
- data/lib/proxes/controllers/component.rb +108 -0
- data/lib/proxes/controllers/permissions.rb +10 -0
- data/lib/proxes/controllers/roles.rb +10 -0
- data/lib/proxes/controllers/users.rb +119 -0
- data/lib/proxes/db.rb +17 -0
- data/lib/proxes/helpers/authentication.rb +45 -0
- data/lib/proxes/helpers/component.rb +40 -0
- data/lib/proxes/helpers/indices.rb +16 -0
- data/lib/proxes/helpers/pundit.rb +39 -0
- data/lib/proxes/helpers/views.rb +41 -0
- data/lib/proxes/loggers/elasticsearch.rb +9 -0
- data/lib/proxes/models/audit_log.rb +12 -0
- data/lib/proxes/models/identity.rb +67 -0
- data/lib/proxes/models/permission.rb +17 -0
- data/lib/proxes/models/role.rb +14 -0
- data/lib/proxes/models/user.rb +57 -0
- data/lib/proxes/policies/application_policy.rb +20 -0
- data/lib/proxes/policies/audit_log_policy.rb +40 -0
- data/lib/proxes/policies/identity_policy.rb +24 -0
- data/lib/proxes/policies/permission_policy.rb +40 -0
- data/lib/proxes/policies/request/root_policy.rb +12 -0
- data/lib/proxes/policies/request/search_policy.rb +15 -0
- data/lib/proxes/policies/request/snapshot_policy.rb +12 -0
- data/lib/proxes/policies/request/stats_policy.rb +15 -0
- data/lib/proxes/policies/request_policy.rb +69 -0
- data/lib/proxes/policies/role_policy.rb +40 -0
- data/lib/proxes/policies/token_policy.rb +46 -0
- data/lib/proxes/policies/user_policy.rb +46 -0
- data/lib/proxes/rake_tasks.rb +59 -0
- data/lib/proxes/request.rb +51 -0
- data/lib/proxes/request/root.rb +10 -0
- data/lib/proxes/request/search.rb +37 -0
- data/lib/proxes/request/snapshot.rb +16 -0
- data/lib/proxes/request/stats.rb +30 -0
- data/lib/proxes/security.rb +59 -0
- data/lib/proxes/seed.rb +10 -0
- data/lib/proxes/services/logger.rb +50 -0
- data/lib/proxes/version.rb +4 -0
- data/migrate/001_tables.rb +47 -0
- data/migrate/002_audit_log.rb +11 -0
- data/package.json +34 -0
- data/proxes.gemspec +44 -0
- data/public/js/bundle.js +28988 -0
- data/src/scripts/app.js +10 -0
- data/views/404.haml +1 -0
- data/views/audit_logs/index.haml +18 -0
- data/views/error.haml +4 -0
- data/views/getting_started.haml +16 -0
- data/views/identity/login.haml +19 -0
- data/views/identity/register.haml +17 -0
- data/views/index.haml +3 -0
- data/views/layout.haml +48 -0
- data/views/partials/delete_form.haml +4 -0
- data/views/partials/form_control.haml +21 -0
- data/views/partials/navbar.haml +25 -0
- data/views/partials/notifications.haml +24 -0
- data/views/partials/pager.haml +19 -0
- data/views/partials/sidebar.haml +32 -0
- data/views/permissions/display.haml +24 -0
- data/views/permissions/edit.haml +11 -0
- data/views/permissions/form.haml +3 -0
- data/views/permissions/index.haml +14 -0
- data/views/permissions/new.haml +10 -0
- data/views/roles/display.haml +33 -0
- data/views/roles/edit.haml +11 -0
- data/views/roles/form.haml +1 -0
- data/views/roles/index.haml +17 -0
- data/views/roles/new.haml +10 -0
- data/views/users/display.haml +32 -0
- data/views/users/edit.haml +11 -0
- data/views/users/identity.haml +3 -0
- data/views/users/index.haml +20 -0
- data/views/users/new.haml +11 -0
- data/views/users/profile.haml +37 -0
- data/views/users/user.haml +3 -0
- metadata +424 -0
data/bin/setup
ADDED
data/config.ru
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#\-o 0.0.0.0 -p 9294
|
3
|
+
libdir = File.expand_path(File.dirname(__FILE__) + '/lib')
|
4
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
5
|
+
|
6
|
+
raise 'Unconfigured' unless ENV['ELASTICSEARCH_URL']
|
7
|
+
|
8
|
+
require 'proxes'
|
9
|
+
require 'proxes/db'
|
10
|
+
|
11
|
+
Sequel.extension :migration
|
12
|
+
Sequel::Migrator.check_current(DB, './migrate')
|
13
|
+
|
14
|
+
use Rack::Static, urls: ['/css', '/js'], root: 'public'
|
15
|
+
use Rack::MethodOverride
|
16
|
+
use Rack::Session::Cookie,
|
17
|
+
key: '_ProxES_session',
|
18
|
+
#:secure=>!TEST_MODE, # Uncomment if only allowing https:// access
|
19
|
+
secret: File.read('.session_secret')
|
20
|
+
|
21
|
+
require 'omniauth'
|
22
|
+
require 'omniauth-identity'
|
23
|
+
require 'proxes/models/identity'
|
24
|
+
require 'proxes/controllers/auth_identity'
|
25
|
+
# OmniAuth.config.test_mode = true
|
26
|
+
use OmniAuth::Builder do
|
27
|
+
# The identity provider is used by the App.
|
28
|
+
provider :identity,
|
29
|
+
fields: [:username],
|
30
|
+
callback_path: '/_proxes/auth/identity/callback',
|
31
|
+
model: ProxES::Identity,
|
32
|
+
on_login: ProxES::AuthIdentity,
|
33
|
+
on_registration: ProxES::AuthIdentity,
|
34
|
+
locate_conditions: ->(req) { { username: req['username'] } }
|
35
|
+
end
|
36
|
+
OmniAuth.config.on_failure = ProxES::AuthIdentity
|
37
|
+
|
38
|
+
# Management App
|
39
|
+
Dir.glob("#{libdir}/proxes/controllers/*.rb").each { |file| require file }
|
40
|
+
|
41
|
+
map '/_proxes' do
|
42
|
+
{
|
43
|
+
'/users' => ProxES::Users,
|
44
|
+
'/roles' => ProxES::Roles,
|
45
|
+
'/permissions' => ProxES::Permissions,
|
46
|
+
'/audit-logs' => ProxES::AuditLogs,
|
47
|
+
}.each do |route, app|
|
48
|
+
map route do
|
49
|
+
run app
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
run ProxES::App
|
54
|
+
end
|
55
|
+
|
56
|
+
# Proxy all Elasticsearch requests
|
57
|
+
require 'proxes/security'
|
58
|
+
map '/' do
|
59
|
+
# Security
|
60
|
+
use ProxES::Security, ProxES::Services::Logger.instance
|
61
|
+
|
62
|
+
# Forward requests to ES
|
63
|
+
run Rack::Proxy.new(backend: ENV['ELASTICSEARCH_URL'])
|
64
|
+
end
|
data/config/logger.yml
ADDED
data/gulpfile.js
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
// From http://jpsierens.com/tutorial-gulp-javascript-2015-react/
|
2
|
+
var gulp = require('gulp');
|
3
|
+
var browserify = require('browserify');
|
4
|
+
var source = require('vinyl-source-stream');
|
5
|
+
var gutil = require('gulp-util');
|
6
|
+
var babelify = require('babelify');
|
7
|
+
var connect = require('gulp-connect');
|
8
|
+
|
9
|
+
// External dependencies you do not want to rebundle while developing,
|
10
|
+
// but include in your application deployment
|
11
|
+
var dependencies = [
|
12
|
+
// 'react',
|
13
|
+
// 'react-dom'
|
14
|
+
// 'react-proxes-components'
|
15
|
+
];
|
16
|
+
// keep a count of the times a task refires
|
17
|
+
var scriptsCount = 0;
|
18
|
+
|
19
|
+
// Gulp tasks
|
20
|
+
// ----------------------------------------------------------------------------
|
21
|
+
gulp.task('scripts', function () {
|
22
|
+
bundleApp(false);
|
23
|
+
});
|
24
|
+
|
25
|
+
gulp.task('deploy', function (){
|
26
|
+
bundleApp(true);
|
27
|
+
});
|
28
|
+
|
29
|
+
gulp.task('watch', function () {
|
30
|
+
gulp.watch(['./src/scripts/**/*.js'], ['scripts']);
|
31
|
+
});
|
32
|
+
|
33
|
+
// When running 'gulp' on the terminal this task will fire.
|
34
|
+
// It will start watching for changes in every .js file.
|
35
|
+
// If there's a change, the task 'scripts' defined above will fire.
|
36
|
+
gulp.task('default', ['scripts','watch']);
|
37
|
+
|
38
|
+
// Private Functions
|
39
|
+
// ----------------------------------------------------------------------------
|
40
|
+
function bundleApp(isProduction) {
|
41
|
+
scriptsCount++;
|
42
|
+
// Browserify will bundle all our js files together in to one and will let
|
43
|
+
// us use modules in the front end.
|
44
|
+
var appBundler = browserify({
|
45
|
+
entries: './src/scripts/app.js',
|
46
|
+
debug: true
|
47
|
+
});
|
48
|
+
|
49
|
+
// If it's not for production, a separate vendors.js file will be created
|
50
|
+
// the first time gulp is run so that we don't have to rebundle things like
|
51
|
+
// react everytime there's a change in the js file
|
52
|
+
if (!isProduction && scriptsCount === 1){
|
53
|
+
// create vendors.js for dev environment.
|
54
|
+
browserify({
|
55
|
+
require: dependencies,
|
56
|
+
debug: true
|
57
|
+
})
|
58
|
+
.bundle()
|
59
|
+
.on('error', gutil.log)
|
60
|
+
.pipe(source('vendors.js'))
|
61
|
+
.pipe(gulp.dest('./public/js/'));
|
62
|
+
}
|
63
|
+
if (!isProduction){
|
64
|
+
// make the dependencies external so they dont get bundled by the
|
65
|
+
// app bundler. Dependencies are already bundled in vendor.js for
|
66
|
+
// development environments.
|
67
|
+
dependencies.forEach(function(dep){
|
68
|
+
appBundler.external(dep);
|
69
|
+
})
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
appBundler
|
74
|
+
// transform ES6 and JSX to ES5 with babelify
|
75
|
+
.transform("babelify", {presets: ["es2015", "react"]})
|
76
|
+
.bundle()
|
77
|
+
.on('error',gutil.log)
|
78
|
+
.pipe(source('bundle.js'))
|
79
|
+
.pipe(gulp.dest('./public/js/'));
|
80
|
+
}
|
data/lib/proxes.rb
ADDED
data/lib/proxes/app.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'proxes/controllers/application'
|
3
|
+
|
4
|
+
module ProxES
|
5
|
+
# Manage your Elasticsearch cluster, user and user sessions
|
6
|
+
class App < Application
|
7
|
+
get '/' do
|
8
|
+
authenticate!
|
9
|
+
haml :index, locals: { title: 'Dashboard' }
|
10
|
+
end
|
11
|
+
|
12
|
+
['/unauthenticated', '/_proxes/unauthenticated'].each do |path|
|
13
|
+
get path do
|
14
|
+
redirect '/auth/identity'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
post '/auth/identity/new' do
|
19
|
+
identity = Identity.new(params['identity'])
|
20
|
+
if identity.valid? && identity.save
|
21
|
+
flash[:info] = 'Successfully Registered. Please log in'
|
22
|
+
redirect '/auth/identity'
|
23
|
+
else
|
24
|
+
flash.now[:warning] = 'Could not complete the registration. Please try again.'
|
25
|
+
haml :'identity/register', locals: { identity: identity }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
post '/auth/identity/callback' do
|
30
|
+
user = User.find_or_create(email: env['omniauth.auth']['info']['email'])
|
31
|
+
|
32
|
+
identity = Identity.find(username: user.email)
|
33
|
+
user.add_identity identity unless identity.user == user
|
34
|
+
|
35
|
+
self.current_user = user
|
36
|
+
flash[:success] = 'Logged In'
|
37
|
+
redirect '/_proxes'
|
38
|
+
end
|
39
|
+
|
40
|
+
delete '/auth/identity' do
|
41
|
+
logout
|
42
|
+
|
43
|
+
flash[:info] = 'Logged Out'
|
44
|
+
|
45
|
+
redirect '/_proxes'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/flash'
|
4
|
+
require 'sinatra/respond_with'
|
5
|
+
require 'proxes/helpers/views'
|
6
|
+
require 'proxes/helpers/pundit'
|
7
|
+
require 'proxes/helpers/authentication'
|
8
|
+
|
9
|
+
module ProxES
|
10
|
+
class Application < Sinatra::Base
|
11
|
+
set :root, ::File.expand_path(::File.dirname(__FILE__) + '/../../../')
|
12
|
+
register Sinatra::Flash, Sinatra::RespondWith
|
13
|
+
helpers ProxES::Helpers::Pundit, ProxES::Helpers::Views, ProxES::Helpers::Authentication
|
14
|
+
|
15
|
+
configure :production do
|
16
|
+
disable :show_exceptions
|
17
|
+
end
|
18
|
+
|
19
|
+
configure :development do
|
20
|
+
set :show_exceptions, :after_handler
|
21
|
+
end
|
22
|
+
|
23
|
+
configure :production, :development do
|
24
|
+
enable :logging
|
25
|
+
end
|
26
|
+
|
27
|
+
not_found do
|
28
|
+
haml :'404', locals: { title: '4 oh 4' }
|
29
|
+
end
|
30
|
+
|
31
|
+
error do
|
32
|
+
error = env['sinatra.error']
|
33
|
+
haml :error, locals: { title: 'Something went wrong', message: error }
|
34
|
+
end
|
35
|
+
|
36
|
+
error ::ProxES::Helpers::NotAuthenticated do
|
37
|
+
flash[:warning] = 'Please log in first.'
|
38
|
+
redirect '/auth/identity'
|
39
|
+
end
|
40
|
+
|
41
|
+
error ::Pundit::NotAuthorizedError do
|
42
|
+
flash[:warning] = 'Please log in first.'
|
43
|
+
redirect '/auth/identity'
|
44
|
+
end
|
45
|
+
|
46
|
+
before (/.*/) do
|
47
|
+
if request.url.match(/.json/)
|
48
|
+
request.accept.unshift('application/json')
|
49
|
+
request.path_info = request.path_info.gsub(/.json/,'')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'proxes/controllers/component'
|
3
|
+
require 'proxes/models/audit_log'
|
4
|
+
require 'proxes/policies/audit_log_policy'
|
5
|
+
|
6
|
+
module ProxES
|
7
|
+
class AuditLogs < Component
|
8
|
+
set model_class: ProxES::AuditLog
|
9
|
+
|
10
|
+
get '/new' do
|
11
|
+
halt 404
|
12
|
+
end
|
13
|
+
|
14
|
+
post '/' do
|
15
|
+
halt 404
|
16
|
+
end
|
17
|
+
|
18
|
+
get '/:id' do
|
19
|
+
halt 404
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/:id/edit' do
|
23
|
+
halt 404
|
24
|
+
end
|
25
|
+
|
26
|
+
put '/:id' do
|
27
|
+
halt 404
|
28
|
+
end
|
29
|
+
|
30
|
+
delete '/:id' do
|
31
|
+
halt 404
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'proxes/controllers/application'
|
3
|
+
|
4
|
+
module ProxES
|
5
|
+
class AuthIdentity < Application
|
6
|
+
get '/auth/identity' do
|
7
|
+
haml :'identity/login', locals: { title: 'Log In' }
|
8
|
+
end
|
9
|
+
|
10
|
+
# Failed Login
|
11
|
+
post '/_proxes/auth/identity/callback' do
|
12
|
+
flash[:warning] = 'Invalid credentials. Please try again.'
|
13
|
+
redirect '/auth/identity'
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/auth/identity/register' do
|
17
|
+
identity = Identity.new
|
18
|
+
haml :'identity/register', locals: { title: 'Register', identity: identity }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'proxes/controllers/application'
|
3
|
+
require 'proxes/helpers/component'
|
4
|
+
|
5
|
+
module ProxES
|
6
|
+
class Component < Application
|
7
|
+
helpers ProxES::Helpers::Component
|
8
|
+
set base_path: nil
|
9
|
+
set view_location: nil
|
10
|
+
|
11
|
+
# List
|
12
|
+
get '/', provides: [:html, :json] do
|
13
|
+
authorize settings.model_class, :list
|
14
|
+
|
15
|
+
actions = {}
|
16
|
+
actions["#{base_path}/new"] = "New #{heading}" if policy(settings.model_class).create?
|
17
|
+
|
18
|
+
respond_to do |format|
|
19
|
+
format.html do
|
20
|
+
haml :"#{view_location}/index",
|
21
|
+
locals: { list: list, title: heading(:list), actions: actions }
|
22
|
+
end
|
23
|
+
format.json do
|
24
|
+
{
|
25
|
+
'items' => list.map { |entity| entity.values },
|
26
|
+
'page' => params[:page],
|
27
|
+
'count' => params[:count],
|
28
|
+
'total' => list.to_a.size
|
29
|
+
}.to_json
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create Form
|
35
|
+
get '/new' do
|
36
|
+
authorize settings.model_class, :create
|
37
|
+
|
38
|
+
entity = settings.model_class.new(permitted_attributes(settings.model_class, :create))
|
39
|
+
haml :"#{view_location}/new", locals: { entity: entity, title: heading(:new) }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Create
|
43
|
+
post '/' do
|
44
|
+
authorize settings.model_class, :create
|
45
|
+
|
46
|
+
entity = settings.model_class.new(permitted_attributes(settings.model_class, :create))
|
47
|
+
if entity.valid? && entity.save
|
48
|
+
flash[:success] = "#{heading} Created"
|
49
|
+
redirect "#{base_path}/#{entity.id}"
|
50
|
+
else
|
51
|
+
haml :"#{view_location}/new", locals: { entity: entity, title: heading(:new) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Read
|
56
|
+
get '/:id' do |id|
|
57
|
+
entity = dataset[id.to_i]
|
58
|
+
halt 404 unless entity
|
59
|
+
authorize entity, :read
|
60
|
+
|
61
|
+
actions = {}
|
62
|
+
actions["#{base_path}/#{entity.id}/edit"] = "Edit #{heading}" if policy(entity).update?
|
63
|
+
|
64
|
+
respond_to do |format|
|
65
|
+
format.html do
|
66
|
+
haml :"#{view_location}/display",
|
67
|
+
locals: { entity: entity, title: heading, actions: actions }
|
68
|
+
end
|
69
|
+
format.json { entity.values.to_json }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Update Form
|
74
|
+
get '/:id/edit' do |id|
|
75
|
+
entity = dataset[id.to_i]
|
76
|
+
halt 404 unless entity
|
77
|
+
authorize entity, :update
|
78
|
+
|
79
|
+
haml :"#{view_location}/edit", locals: { entity: entity, title: heading(:edit) }
|
80
|
+
end
|
81
|
+
|
82
|
+
# Update
|
83
|
+
put '/:id' do |id|
|
84
|
+
entity = dataset[id.to_i]
|
85
|
+
halt 404 unless entity
|
86
|
+
authorize entity, :update
|
87
|
+
|
88
|
+
entity.set(permitted_attributes(settings.model_class, :update))
|
89
|
+
if entity.valid? && entity.save
|
90
|
+
flash[:success] = "#{heading} Updated"
|
91
|
+
redirect "#{base_path}/#{entity.id}"
|
92
|
+
else
|
93
|
+
haml :"#{view_location}/edit", locals: { entity: entity, title: heading(:edit) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
delete '/:id' do |id|
|
98
|
+
entity = dataset[id.to_i]
|
99
|
+
halt 404 unless entity
|
100
|
+
authorize entity, :delete
|
101
|
+
|
102
|
+
entity.destroy
|
103
|
+
|
104
|
+
flash[:success] = "#{heading} Deleted"
|
105
|
+
redirect base_path.to_s
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|