proxes 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/src/scripts/app.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import ReactDOM from 'react-dom';
|
3
|
+
import ProxesComponents from 'react-proxes-components/react-proxes-components';
|
4
|
+
|
5
|
+
ReactDOM.render(<ProxesComponents pollInterval="30000"/>, document.getElementById('react-dashboard'));
|
6
|
+
|
7
|
+
// ReactDOM.render(
|
8
|
+
// <Health store={new ESStore()}/>,
|
9
|
+
// document.getElementById('indexlist')
|
10
|
+
// );
|
data/views/404.haml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
%h2 4 oh 4
|
@@ -0,0 +1,18 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
%table.table.table-striped
|
5
|
+
%thead
|
6
|
+
%tr
|
7
|
+
%th User email
|
8
|
+
%th Action
|
9
|
+
%th Created at
|
10
|
+
%tbody
|
11
|
+
-list.each do |entity|
|
12
|
+
%tr
|
13
|
+
%td
|
14
|
+
%a{ href: "/_proxes/users/#{entity.user.id}" }= entity.user.email
|
15
|
+
%td
|
16
|
+
= entity.action
|
17
|
+
%td
|
18
|
+
= entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
data/views/error.haml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-success
|
4
|
+
.panel-heading
|
5
|
+
You can now start using this Elasticsearch cluster:
|
6
|
+
.panel-body
|
7
|
+
%h4 Send Data
|
8
|
+
%pre
|
9
|
+
:plain
|
10
|
+
curl -X POST '#{ request.base_url }/#{ current_user.email }/test' \
|
11
|
+
-u #{ current_user.email }:yourpassword -d '{"message":"Get cracking!"}'
|
12
|
+
|
13
|
+
%h4 Search
|
14
|
+
%pre
|
15
|
+
curl -X GET '#{ request.base_url }/_search' -u #{ current_user.email }:yourpassword
|
16
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
.row
|
2
|
+
.col-sm-3
|
3
|
+
.col-sm-6
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-heading
|
6
|
+
ProxES Login
|
7
|
+
.panel-body
|
8
|
+
%form{ method: 'post', action: '/_proxes/auth/identity/callback' }
|
9
|
+
.form-group
|
10
|
+
%label.control-label Username
|
11
|
+
%input.form-control.border-input{ name: 'username' }
|
12
|
+
.form-group
|
13
|
+
%label.control-label Password
|
14
|
+
%input.form-control.border-input{ name: 'password', type: 'password' }
|
15
|
+
%button.btn.btn-primary{ type: 'submit' } Log In
|
16
|
+
.pull-right
|
17
|
+
No account yet?
|
18
|
+
%a.btn.btn-default{ href: '/auth/identity/register' } Register
|
19
|
+
.col-sm-3
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
%h1 ProxES Registration
|
4
|
+
.row
|
5
|
+
.col-md-2
|
6
|
+
.col-md-8
|
7
|
+
.panel.panel-default
|
8
|
+
.panel-heading
|
9
|
+
ProxES Registration
|
10
|
+
.panel-body
|
11
|
+
%form.form-horizontal{ method: 'post', action: '/_proxes/auth/identity/new' }
|
12
|
+
= form_control(:username, identity, label: 'Email', placeholder: 'Your email address')
|
13
|
+
= form_control(:password, identity, label: 'Password', type: :password)
|
14
|
+
= form_control(:password_confirmation, identity, label: 'Confirm Password', type: :password)
|
15
|
+
|
16
|
+
%button.btn.btn-primary{ type: 'submit' } Register
|
17
|
+
.col-md-2
|
data/views/index.haml
ADDED
data/views/layout.haml
ADDED
@@ -0,0 +1,48 @@
|
|
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
|
+
%link{ rel: 'apple-touch-icon', sizes: '76x76', href: '/assets/img/apple-icon.png' }
|
8
|
+
|
9
|
+
%title
|
10
|
+
ProxES
|
11
|
+
- if defined? title
|
12
|
+
= "- #{title}"
|
13
|
+
|
14
|
+
%meta{ name: 'description', content: '' }
|
15
|
+
%meta{ name: 'author', content: '' }
|
16
|
+
|
17
|
+
/ Le styles
|
18
|
+
%link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', media: 'screen' }
|
19
|
+
%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' }
|
20
|
+
%link{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.css', media: 'screen' }
|
21
|
+
%link{ rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', media: 'screen' }
|
22
|
+
/[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
23
|
+
/[if lt IE 9] <script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
24
|
+
|
25
|
+
%body
|
26
|
+
#wrapper
|
27
|
+
= haml :'partials/navbar', locals: { title: (defined?(title) ? title : 'ProxES') }
|
28
|
+
#page-wrapper
|
29
|
+
.row
|
30
|
+
.col-md-12
|
31
|
+
-if defined? title
|
32
|
+
%h1.page-header= title
|
33
|
+
= haml :'partials/notifications'
|
34
|
+
= yield
|
35
|
+
%footer.footer.text-muted.text-center
|
36
|
+
%hr
|
37
|
+
.copyright
|
38
|
+
:plain
|
39
|
+
© <script>document.write(new Date().getFullYear())</script>, JadeIT
|
40
|
+
|
41
|
+
|
42
|
+
/ Placed at the end of the document so the pages load faster
|
43
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js' }
|
44
|
+
%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' }
|
45
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/metisMenu/2.5.2/metisMenu.min.js' }
|
46
|
+
%script{ type: 'text/javascript', src: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' }
|
47
|
+
%script{ type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.min.js' }
|
48
|
+
%script{ type: 'text/javascript', src: '/js/bundle.js' }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
%div{ class: "form-group#{model.errors[field] ? ' has-error' : ''}" }
|
2
|
+
%label.col-sm-3.control-label{ for: attributes[:id] }= label
|
3
|
+
.col-sm-9
|
4
|
+
- type = attributes.delete(:type)
|
5
|
+
- if type == 'select'
|
6
|
+
- options = attributes.delete(:options)
|
7
|
+
%select{attributes}
|
8
|
+
- if attributes[:multiple]
|
9
|
+
- options.each do |k,v| k ||= v; v ||= k;
|
10
|
+
%option{ value: k, selected: (model.send(field).map(&:id).include? k)}= v
|
11
|
+
- else
|
12
|
+
%option{ value: ""} -- Select One --
|
13
|
+
- options.each do |k,v| k ||= v; v ||= k;
|
14
|
+
%option{ value: k, selected: (k.to_s == model[field].to_s)}= v
|
15
|
+
- elsif type == 'textarea'
|
16
|
+
%textarea{attributes}
|
17
|
+
= model[field]
|
18
|
+
- else
|
19
|
+
%input{attributes, type: type, value: model[field]}
|
20
|
+
- if model.errors[field]
|
21
|
+
%p.help-block.text-danger= model.errors[field].join(', ')
|
@@ -0,0 +1,25 @@
|
|
1
|
+
.navbar.navbar-default.navbar-static-top{ role: 'navigation', style: 'margin-bottom: 0' }
|
2
|
+
.navbar-header
|
3
|
+
%span.navbar-brand
|
4
|
+
ProxES
|
5
|
+
- if defined? title
|
6
|
+
= "- #{title}"
|
7
|
+
%button.navbar-toggle.collapsed{ 'type' => 'button', 'data-toggle' => 'collapse', 'data-target' => '#navbar', 'aria-expanded' => 'false', 'aria-controls' => 'navbar' }
|
8
|
+
%span.sr-only Toggle navigation
|
9
|
+
%span.icon-bar.bar1
|
10
|
+
%span.icon-bar.bar2
|
11
|
+
%span.icon-bar.bar3
|
12
|
+
-if current_user
|
13
|
+
%form.nav.navbar-top-links.navbar-form.navbar-right{ action: '/_proxes/auth/identity', method: 'post' }
|
14
|
+
%a.btn.btn-default{ href: "/_proxes/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: '/auth/identity' }
|
23
|
+
Log In
|
24
|
+
.navbar-default.sidebar{ role: 'navigation' }
|
25
|
+
= haml :'partials/sidebar'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
- if flash[:danger]
|
2
|
+
.alert.alert-danger.alert-dismissible{ role: "alert" }
|
3
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
4
|
+
- (flash[:danger].is_a?(Array) ? flash[:danger] : [flash[:danger]]).each do |msg|
|
5
|
+
%span= msg
|
6
|
+
|
7
|
+
- if flash[:warning]
|
8
|
+
.alert.alert-warning.alert-dismissible{ role: "alert" }
|
9
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
10
|
+
- (flash[:warning].is_a?(Array) ? flash[:warning] : [flash[:warning]]).each do |msg|
|
11
|
+
%span= msg
|
12
|
+
|
13
|
+
- if flash[:success]
|
14
|
+
.alert.alert-success.alert-dismissible{ role: "alert" }
|
15
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
16
|
+
- (flash[:success].is_a?(Array) ? flash[:success] : [flash[:success]]).each do |msg|
|
17
|
+
%span= msg
|
18
|
+
|
19
|
+
|
20
|
+
- if flash[:info]
|
21
|
+
.alert.alert-info.alert-dismissible{ role: "alert" }
|
22
|
+
%button.close{ 'type' => 'button', 'aria-hidden' => 'true', 'area-label' => 'true', 'data-dismiss' => 'alert' } ×
|
23
|
+
- (flash[:info].is_a?(Array) ? flash[:info] : [flash[:info]]).each do |msg|
|
24
|
+
%span= msg
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<nav aria-label="Page navigation">
|
2
|
+
<p class="text-center">
|
3
|
+
Showing <%= list.current_page_record_range %> of <%= list.pagination_record_count %> records
|
4
|
+
</p>
|
5
|
+
<ul class="pager">
|
6
|
+
<li>
|
7
|
+
<a href="<%= base_path %>?page=1&count=<%= list.page_size %>">First</a>
|
8
|
+
</li>
|
9
|
+
<li<% if list.first_page? %> class="disabled"<% end %>>
|
10
|
+
<a href="<%= prev_link %>">Previous</a>
|
11
|
+
</li>
|
12
|
+
<li<% if list.last_page? %> class="disabled"<% end %>>
|
13
|
+
<a href="<%= next_link %>">Next</a>
|
14
|
+
</li>
|
15
|
+
<li>
|
16
|
+
<a href="<%= base_path %>?page=<%= list.page_count %>&count=<%= list.page_size %>">Last</a>
|
17
|
+
</li>
|
18
|
+
</ul>
|
19
|
+
</nav>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
%ul.nav.nav-pills.nav-stacked
|
2
|
+
- if defined?(current_user) && current_user
|
3
|
+
%li
|
4
|
+
%a{ href: '/_proxes' }
|
5
|
+
%i.fa.fa-dashboard.fa-fw
|
6
|
+
Dashboard
|
7
|
+
- if current_user.super_admin?
|
8
|
+
%li
|
9
|
+
%a{ href: '/_proxes/users' }
|
10
|
+
%i.fa.fa-user.fa-fw
|
11
|
+
Users
|
12
|
+
%li
|
13
|
+
%a{ href: '/_proxes/roles' }
|
14
|
+
%i.fa.fa-group.fa-fw
|
15
|
+
Roles
|
16
|
+
%li
|
17
|
+
%a{ href: '/_proxes/permissions' }
|
18
|
+
%i.fa.fa-check-square-o.fa-fw
|
19
|
+
Permissions
|
20
|
+
%li
|
21
|
+
%a{ href: '/_proxes/settings' }
|
22
|
+
%i.fa.fa-cog.fa-fw
|
23
|
+
Settings
|
24
|
+
- else
|
25
|
+
%li.active
|
26
|
+
%a{ href: '/auth/identity' }
|
27
|
+
%i.fa.fa-user.fa-fw
|
28
|
+
Log In
|
29
|
+
%li
|
30
|
+
%a{ href: '/auth/identity/register' }
|
31
|
+
%i.fa.fa-pencil-square-o.fa-fw
|
32
|
+
Register
|
@@ -0,0 +1,24 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%p.description
|
7
|
+
%label Role:
|
8
|
+
= entity.role.name
|
9
|
+
%p.description
|
10
|
+
%label Verb:
|
11
|
+
= entity.verb
|
12
|
+
%p.description
|
13
|
+
%label Pattern:
|
14
|
+
= entity.pattern
|
15
|
+
|
16
|
+
.row
|
17
|
+
.col-md-6
|
18
|
+
%a.btn.btn-default{ href: "/_proxes/permissions/#{entity.id}/edit" } Edit
|
19
|
+
.col-md-6.text-right
|
20
|
+
- if policy(entity).delete?
|
21
|
+
%form{ method: 'post', action: "/_proxes/permissions/#{entity.id}" }
|
22
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
23
|
+
%button.btn.btn-warning{ type: 'submit' } Delete
|
24
|
+
.col-md-2
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: "/_proxes/permissions/#{entity.id}" }
|
7
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
8
|
+
= haml :'permissions/form', locals: { entity: entity }
|
9
|
+
%button.btn.btn-primary{ type: 'submit' }
|
10
|
+
Update Permission
|
11
|
+
.col-md-2
|
@@ -0,0 +1,14 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
.panel-heading VERB Pattern
|
5
|
+
%table.table.table-striped
|
6
|
+
%tbody
|
7
|
+
-list.each do |entity|
|
8
|
+
%tr
|
9
|
+
%td
|
10
|
+
%a.btn-block{ href: "/_proxes/permissions/#{entity.id}" }
|
11
|
+
= entity.verb
|
12
|
+
= entity.pattern
|
13
|
+
.panel-body.text-right
|
14
|
+
%a.btn.btn-primary{ href: '/_proxes/permissions/new' } New Permission
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: '/_proxes/permissions' }
|
7
|
+
= haml :'permissions/form', locals: { entity: entity }
|
8
|
+
%button.btn.btn-primary.btn{ type: 'submit' }
|
9
|
+
Create Permission
|
10
|
+
.col-md-2
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%p.description
|
7
|
+
%label Name:
|
8
|
+
= entity.name
|
9
|
+
|
10
|
+
.row
|
11
|
+
.col-md-6
|
12
|
+
%a.btn.btn-default{ href: "/_proxes/roles/#{entity.id}/edit" } Edit
|
13
|
+
.col-md-6.text-right
|
14
|
+
- if policy(entity).delete?
|
15
|
+
%form{ method: 'post', action: "/_proxes/roles/#{entity.id}" }
|
16
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
17
|
+
%button.btn.btn-warning{ type: 'submit' } Delete
|
18
|
+
.col-md-2
|
19
|
+
|
20
|
+
.row
|
21
|
+
.col-md-2
|
22
|
+
.col-md-8
|
23
|
+
.panel.panel-default
|
24
|
+
.panel-heading
|
25
|
+
%h3 Permissions
|
26
|
+
%table.table
|
27
|
+
- entity.permissions.each do |permission|
|
28
|
+
%tr
|
29
|
+
%td
|
30
|
+
%a.btn-block{ href: "/_proxes/permissions/#{entity.id}" }
|
31
|
+
= permission.verb
|
32
|
+
= permission.pattern
|
33
|
+
.col-md-2
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
%form.form-horizontal{ method: 'post', action: "/_proxes/roles/#{entity.id}" }
|
7
|
+
%input{ name: '_method', value: 'PUT', type: 'hidden' }
|
8
|
+
= haml :'roles/form', locals: { entity: entity }
|
9
|
+
%button.btn.btn-primary{ type: 'submit' }
|
10
|
+
Update Role
|
11
|
+
.col-md-2
|
@@ -0,0 +1 @@
|
|
1
|
+
= form_control(:name, entity)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-12
|
3
|
+
.panel.panel-default
|
4
|
+
%table.table.table-striped
|
5
|
+
%thead
|
6
|
+
%tr
|
7
|
+
%th Name
|
8
|
+
%th Permissions
|
9
|
+
%tbody
|
10
|
+
-list.each do |entity|
|
11
|
+
%tr
|
12
|
+
%td
|
13
|
+
%a{ href: "/_proxes/roles/#{entity.id}" }= entity.name
|
14
|
+
%td
|
15
|
+
= entity.permissions_dataset.count
|
16
|
+
.panel-body.text-right
|
17
|
+
%a.btn.btn-primary{ href: '/_proxes/roles/new' } New Role
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-2
|
3
|
+
.col-md-8
|
4
|
+
.panel.panel-default
|
5
|
+
.panel-body
|
6
|
+
.author
|
7
|
+
%img.pull-right.thumbnail{ src: entity.gravatar }
|
8
|
+
%h4.title= entity.email
|
9
|
+
|
10
|
+
%hr
|
11
|
+
%p.description
|
12
|
+
%label Name:
|
13
|
+
= entity.name
|
14
|
+
%p.description
|
15
|
+
%label Surname:
|
16
|
+
= entity.surname
|
17
|
+
%p.description
|
18
|
+
%label Roles:
|
19
|
+
= entity.roles_dataset.map(:name).map(&:titlecase).join(', ')
|
20
|
+
%p.description
|
21
|
+
%label Signed up:
|
22
|
+
= entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
23
|
+
|
24
|
+
.row
|
25
|
+
.col-md-6
|
26
|
+
%a.btn.btn-default{ href: "/_proxes/users/#{entity.id}/edit" } Edit
|
27
|
+
.col-md-6.text-right
|
28
|
+
- if policy(entity).delete?
|
29
|
+
%form{ method: 'post', action: "/_proxes/users/#{entity.id}" }
|
30
|
+
%input{ name: '_method', value: 'DELETE', type: 'hidden' }
|
31
|
+
%button.btn.btn-warning{ type: 'submit' } Delete
|
32
|
+
.col-md-2
|