symphonia 4.1.3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +27 -1
  4. data/app/assets/javascripts/symphonia/application.js +3 -3
  5. data/app/assets/javascripts/symphonia/symphonia_bootstrap_dialog.js +23 -23
  6. data/app/assets/stylesheets/symphonia/_font_awesome.scss +8 -6
  7. data/app/assets/stylesheets/symphonia/_layout.scss +33 -1
  8. data/app/assets/stylesheets/symphonia/basic.scss +3 -99
  9. data/app/assets/stylesheets/symphonia/filters.scss +3 -5
  10. data/app/assets/stylesheets/symphonia/symphonia_bootstrap.scss +1 -1
  11. data/app/controllers/symphonia/accounts_controller.rb +7 -3
  12. data/app/controllers/symphonia/application_controller.rb +2 -1
  13. data/app/controllers/symphonia/users_controller.rb +17 -29
  14. data/app/helpers/symphonia/application_helper.rb +48 -26
  15. data/app/models/symphonia/preference.rb +5 -5
  16. data/app/models/symphonia/user.rb +3 -35
  17. data/app/models/symphonia/user_ability.rb +46 -0
  18. data/app/views/common/403.html.erb +4 -3
  19. data/app/views/layouts/symphonia/application.html.erb +4 -4
  20. data/app/views/symphonia/accounts/_detail.html.erb +21 -18
  21. data/app/views/symphonia/common/_filters.html.erb +15 -15
  22. data/app/views/symphonia/common/_share_links.html.erb +2 -3
  23. data/app/views/symphonia/users/_form.html.erb +1 -6
  24. data/app/views/symphonia/users/show.html.erb +15 -20
  25. data/config/locales/cs.yml +3 -2
  26. data/db/migrate/20130714140500_create_users.rb +0 -2
  27. data/db/seeds.rb +3 -3
  28. data/lib/generators/symphonia/entity_controller/entity_controller_generator.rb +2 -2
  29. data/lib/generators/symphonia/entity_controller/templates/{controller.rb → controller.rb.tt} +0 -0
  30. data/lib/symphonia/admin_constraint.rb +1 -1
  31. data/lib/symphonia/base_controller.rb +9 -17
  32. data/lib/symphonia/controller_extensions.rb +5 -15
  33. data/lib/symphonia/engine.rb +12 -43
  34. data/lib/symphonia/form_builder.rb +17 -16
  35. data/lib/symphonia/menu_manager.rb +15 -11
  36. data/lib/symphonia/model_attributes/attribute.rb +3 -3
  37. data/lib/symphonia/object.rb +9 -9
  38. data/lib/symphonia/spec_helper.rb +8 -4
  39. data/lib/symphonia/user_management.rb +1 -1
  40. data/lib/symphonia/version.rb +1 -1
  41. data/lib/symphonia.rb +12 -9
  42. data/spec/factories/factories.rb +0 -4
  43. data/spec/models/user_spec.rb +39 -2
  44. data/spec/spec_helper.rb +0 -1
  45. data/spec/support/stub_users.rb +7 -7
  46. metadata +41 -140
  47. data/app/controllers/symphonia/roles_controller.rb +0 -39
  48. data/app/models/symphonia/role.rb +0 -55
  49. data/app/views/symphonia/roles/_form.html.erb +0 -26
  50. data/app/views/symphonia/roles/edit.html.erb +0 -5
  51. data/app/views/symphonia/roles/index.html.erb +0 -6
  52. data/app/views/symphonia/roles/new.html.erb +0 -4
  53. data/app/views/symphonia/roles/show.html.erb +0 -11
  54. data/db/migrate/20130714140501_create_roles.rb +0 -18
  55. data/db/migrate/20210509141420_roles_change_permissions_to_json.rb +0 -18
  56. data/db/migrate/20210509180525_roles_change_permissions_to_native_json.rb +0 -7
  57. data/lib/symphonia/permissions.rb +0 -93
  58. data/spec/controllers/roles_controller_spec.rb +0 -12
  59. data/spec/models/role_spec.rb +0 -13
  60. data/spec/requests/roles_spec.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d64b152203dc6bf578501b1095fbd81e2cbe5ede1fd34a4eb020ffdf54ee8f57
4
- data.tar.gz: 1c87c27bf654326f38c574bfb4afcf0eb0d7a19e442fa2581438d90953b7bbe9
3
+ metadata.gz: 71cb8a41bead7977d784fbb826c54a059b74f9cc75f43de46e67bbb8fd547cea
4
+ data.tar.gz: aa49eb8c8b095422abd9bb3c65105c3bfc79bf3cb82d2e8ea6655751cc9f15a2
5
5
  SHA512:
6
- metadata.gz: a328cfbc0aae03353f32c05a5516f1a75525fb79660eaa01addbd3562a471b7d38be4aa0f0f7618328cd77bd55e7296e830a9205043d78c6a3f7df17971619ea
7
- data.tar.gz: 14d656d24c7c1741d52ee4faa3cff9eebfabaea0b6ff1de737c7b99e1329e12f6fcad977a76bcec1a07fecd072429f132c7fe9446649cd51502b93f8ecf979c2
6
+ metadata.gz: 98a480e8c8c1e1a31c887c313fc6bd682774cc397277ff7edf10da58583d59badca233903adb447d131d98b704573d2dbdd8fd90e61465ae146eb126a4e85c36
7
+ data.tar.gz: bc42c7d29dcb974fee96e7749315449c77f44843a2b8cde034a5964dc4aec0c9fdfa25a5224605165b75453e24a23b6ca53d35ef59b2e3c620e1b00f6fe11216
data/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ ## [4.2.0] - 2022-04-07
9
+ ### Removed
10
+ - awesome_nested_set dependency
11
+ ### Changed
12
+ - start with Ruby3 support
13
+
8
14
  ## [4.1.3] - 2022-03-02
9
15
  ### Changed
10
16
  - update sidekiq
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Symphonia
2
- > simple core toolkit for my rails apps
2
+
3
+ simple core toolkit for my rails apps
3
4
 
4
5
  ## Installation
5
6
 
@@ -13,6 +14,7 @@ after `bundle install` run post-installation: `rails g symphonia:setup`
13
14
 
14
15
  > Setup prepare `config/initializers/settings.rb`, create `spec/spec_helper.rb`, add stylesheets and javascripts references and copy basic layout.
15
16
 
17
+ ## Configuration
16
18
 
17
19
  ## Upgrade to v4.0
18
20
  1. update Gemfile:
@@ -30,3 +32,27 @@ And `bundle update`
30
32
  export THOR_MERGE=vimdiff
31
33
  rails app:update
32
34
  ```
35
+ ## Upgrade to v5.0
36
+ Version 5 remove sprockets bootstrap, font-awesome and others CSS/JS things. It expect that assets will be managed by webpacker (or similar) FE technology.
37
+
38
+ Also remove `Role` model and whole permissions custom logic. Its replace standardized CanCanCan gem (https://github.com/CanCanCommunity/cancancan/tree/develop/docs)
39
+
40
+ ### Sprockets fallback
41
+ For fallback add to Gemfile
42
+ ```ruby
43
+ gem "bootstrap", "~> 4.6"
44
+ gem "jquery-rails"
45
+ gem "jquery-ui-rails"
46
+ gem "listen"
47
+ gem "sass-rails"
48
+ gem "turbolinks"
49
+ gem 'font-awesome-sass', '~> 6.2.0'
50
+ ```
51
+ in your "app/assets/stylessheets/general.scss" make sure symphonia is imported
52
+ ```scss
53
+ @import 'symphonia/basic';
54
+ @import 'symphonia/layout';
55
+ ```
56
+
57
+ ### CanCanCan
58
+ For user there is `Symphonia::UserAbility` which defined permissions for User model + for admin add basic CRUD operation for `:all`.
@@ -7,8 +7,8 @@
7
7
  //= require symphonia/_core
8
8
  //= require symphonia/Sortable
9
9
 
10
- //= require bootstrap-datepicker/core
11
- //= require bootstrap-datepicker/locales/bootstrap-datepicker.cs.js
10
+ // require bootstrap-datepicker/core
11
+ // require bootstrap-datepicker/locales/bootstrap-datepicker.cs.js
12
12
 
13
13
  //= require_self
14
14
  //= require symphonia/symphonia_bootstrap_dialog
@@ -155,4 +155,4 @@ SymphoniaCheckboxes = {
155
155
 
156
156
  return input;
157
157
  }
158
- };
158
+ };
@@ -1,42 +1,42 @@
1
1
  /**
2
2
  * Symphonia modal dialog pop-up.
3
3
  * @param {String} id
4
- * @param {Object} options
5
- * @param {String} options.title - Title of dialog window.
6
- * @param {Boolean} options.force - If dialog element exists, will remove and replace new one.
7
- * @param {String} options.text - Text for body of dialog window.
8
- * @param {String} options.html - Content (html) for body of dialog window.
9
- * @param {String} options.submit - Text of submit button. If provided generate submit button.
10
- * @param {Boolean} options.large - Use Large modal
4
+ * @param {Object} opts
5
+ * @param {String} opts.title - Title of dialog window.
6
+ * @param {Boolean} opts.force - If dialog element exists, will remove and replace new one.
7
+ * @param {String} opts.text - Text for body of dialog window.
8
+ * @param {String} opts.html - Content (html) for body of dialog window.
9
+ * @param {String} opts.submit - Text of submit button. If provided generate submit button.
10
+ * @param {Boolean} opts.large - Use Large modal
11
11
  */
12
- SymphoniaDialog = function (id, options) {
13
- var options = $.extend(options, {});
12
+ SymphoniaDialog = function (id, opts) {
13
+ const options = $.extend(opts, {});
14
14
  if (options["force"] === undefined)
15
15
  options["force"] = true;
16
16
 
17
17
  this.id = id || 'ajax_modal';
18
- var m = document.getElementById(this.id);
18
+ const m = document.getElementById(this.id);
19
19
 
20
20
  // var currentDialog = document.getElementById(this.id + "__symphonia_dialog");
21
21
  // if (currentDialog) {
22
22
  // currentDialog.remove();
23
23
  // }
24
24
 
25
- var dialog = document.createElement("div");
26
- var modalDialog = document.createElement("div");
25
+ const dialog = document.createElement("div");
26
+ const modalDialog = document.createElement("div");
27
27
  modalDialog.className = "modal-dialog";
28
28
  if (options["large"]) {
29
29
  modalDialog.classList.add("modal-lg")
30
30
  }
31
31
  dialog.setAttribute("role", "document");
32
32
 
33
- var content = document.createElement("div");
33
+ const content = document.createElement("div");
34
34
  content.className = "modal-content";
35
- var heading = document.createElement("div");
35
+ const heading = document.createElement("div");
36
36
  heading.className = "modal-header";
37
- var modalTitle = document.createElement("h5");
37
+ const modalTitle = document.createElement("h5");
38
38
  modalTitle.className = "modal-title";
39
- var body = document.createElement("div");
39
+ const body = document.createElement("div");
40
40
 
41
41
  body.className = "modal-body";
42
42
  dialog.id = this.id;
@@ -46,7 +46,7 @@ SymphoniaDialog = function (id, options) {
46
46
  // =-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-
47
47
 
48
48
  this.appendSubmitButton = function (label) {
49
- var submitButton = document.createElement('button');
49
+ const submitButton = document.createElement('button');
50
50
  submitButton.onclick = this.submit;
51
51
  submitButton.innerText = (label === true) && 'Submit' || label;
52
52
  submitButton.className = "btn btn-primary";
@@ -54,14 +54,14 @@ SymphoniaDialog = function (id, options) {
54
54
  return submitButton;
55
55
  };
56
56
  this.submit = function () {
57
- var form = dialog.querySelector("form");
57
+ const form = dialog.querySelector("form");
58
58
  if (form)
59
59
  form.submit();
60
60
  };
61
61
  this.show = function () {
62
62
  // dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
63
63
  // dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
64
- var t = dialog.querySelector(".title");
64
+ const t = dialog.querySelector(".title");
65
65
  if (t && t.innerHTML === '') {
66
66
  this.title = modalTitle.innerHTML;
67
67
  t.remove();
@@ -83,7 +83,7 @@ SymphoniaDialog = function (id, options) {
83
83
 
84
84
  modalTitle.innerText = options.title || '';
85
85
 
86
- var closeButton = document.createElement("button");
86
+ const closeButton = document.createElement("button");
87
87
  closeButton.className = "close fa fa-times";
88
88
  closeButton.dataset['dismiss'] = "modal";
89
89
  heading.appendChild(modalTitle);
@@ -114,7 +114,7 @@ SymphoniaDialog = function (id, options) {
114
114
  dialog.appendChild(modalDialog);
115
115
 
116
116
  if (options.force) {
117
- var currentDialog = document.getElementById(dialog.id);
117
+ const currentDialog = document.getElementById(dialog.id);
118
118
  if (currentDialog)
119
119
  currentDialog.remove();
120
120
  }
@@ -130,7 +130,7 @@ SymphoniaDialog.prototype.close = function () {
130
130
  };
131
131
  window.Symphonia.dialog = {
132
132
  show: function(IDcontainer, options) {
133
- var modal = new SymphoniaDialog(IDcontainer, options);
133
+ const modal = new SymphoniaDialog(IDcontainer, options);
134
134
  modal.show();
135
135
  }
136
- }
136
+ }
@@ -1,25 +1,27 @@
1
- @import 'font-awesome';
1
+ @import "font-awesome";
2
2
  /* Font awesome aliases */
3
3
  .fa-add {
4
- @extend .fa-plus-circle !optional;
4
+ //@include fa-icon-solid($fa-var-circle-plus);
5
+ @extend .fa-circle-plus !optional;
5
6
  }
6
7
  .fa-delete, .fa-del {
7
- @extend .fa-trash-o !optional;
8
+ @include fa-icon-solid($fa-var-trash-can);
8
9
  }
9
10
  .fa-back {
10
- @extend .fa-chevron-left !optional;
11
+ @include fa-icon-solid($fa-var-chevron-left);
11
12
  }
12
13
  .fa-true {
13
14
  @extend .fa-check !optional;
15
+ @include fa-icon-solid($fa-var-check);
14
16
  }
15
17
  .fa-false {
16
- @extend .fa-times !optional;
18
+ @include fa-icon-solid($fa-var-times);
17
19
  }
18
20
  .fa-notice {
19
21
  @extend .fa-check-circle !optional;
20
22
  }
21
23
  .fa-error {
22
- @extend .fa-times-circle !optional;
24
+ @extend .circle-exclamation !optional;
23
25
  }
24
26
  .alert .fa-info {
25
27
  @extend .fa-info-circle !optional;
@@ -1,4 +1,4 @@
1
- @import "bootstrap";
1
+ @import "/bootstrap";
2
2
 
3
3
  // fixed navbar
4
4
  body > .container {
@@ -38,3 +38,35 @@ footer.footer {
38
38
  @extend .d-print-none;
39
39
  }
40
40
  }
41
+
42
+ /* TABLE */
43
+ @mixin inactive-row {
44
+ opacity: 0.5
45
+ }
46
+ td.price {
47
+ text-align: right;
48
+ }
49
+ table.table {
50
+ th a.asc {
51
+ &:after {
52
+ content: "\2191";
53
+ }
54
+ }
55
+ th a.desc {
56
+ &:after {
57
+ content: "\2193";
58
+ }
59
+ }
60
+ tr.status {
61
+ &--lock, &--inactive, &--archived {
62
+ @include inactive-row;
63
+ }
64
+ }
65
+ .buttons {
66
+ text-align: right;
67
+ }
68
+ }
69
+
70
+ /* FORM */
71
+ .required label, label[required], label.required, .has-error {color: red !important;}
72
+ .required label:after, label[required]:after, label.required:after { content: '* '}
@@ -1,85 +1,13 @@
1
- @import "_font_awesome";
1
+ @import "./_font_awesome";
2
2
 
3
3
  .page-header.title, .page-header.title h1 {
4
4
  margin-top: 0;
5
5
  }
6
- @mixin inactive-row {
7
- opacity: 0.5
8
- }
6
+
9
7
  .reorder, .reorder label {
10
8
  cursor: move;
11
9
  }
12
10
 
13
- .flash {
14
- border: 1px solid;
15
- margin: 10px 0px;
16
- padding:15px 10px 15px 10px;
17
- background-repeat: no-repeat;
18
- background-position: 10px center;
19
- position:relative;
20
- line-height: 30px;
21
- &>i.icon:first-child {
22
- font-family: FontAwesome;
23
- font-size: 30px;
24
-
25
- font-style: normal;
26
- position:absolute;
27
- top: 50%;
28
- margin-top: -15px;
29
- }
30
- &>span.flash-content {
31
- padding-left: 35px;
32
-
33
- }
34
- }
35
- .info {
36
- color: #00529B;
37
- background-color: #BDE5F8;
38
- }
39
- .notice {
40
- color: #4F8A10;
41
- background-color: #DFF2BF;
42
- &>i.icon:first-child:before {
43
- content: "\f05d"
44
- }
45
- }
46
-
47
- .nodata, .no-data {
48
- @extend .flash;
49
- @extend .info;
50
- text-align: center;
51
- border-width: 3px;
52
- }
53
-
54
- div.error_explanation {
55
- color: #D63301;
56
- background-color: #FFCCBA;
57
- border: 1px solid rgba(255,0,0,0.5);
58
- position: relative;
59
- margin: 0 0 25px 0;
60
- h2 {
61
- display: none;
62
- }
63
- ul {
64
- margin: 0;
65
- li {
66
- line-height: 25px;
67
- }
68
- }
69
- &>p {
70
- background-color: rgba(255,255,255,0.5);
71
- margin: 0;
72
- padding: 5px;
73
- text-shadow: 0 0 5px #FFFFFF;
74
- }
75
- &>p:before {
76
- font-family: FontAwesome;
77
- margin-right: 5px;
78
- font-size: 20px;
79
- content: "\f071";
80
- }
81
- }
82
-
83
11
  #account-extra-details {
84
12
  dt {
85
13
  width: 40%;
@@ -115,8 +43,6 @@ td.buttons {
115
43
  .contextual {@extend .pull-right !optional}
116
44
  .contextual input, .contextual select {font-size:0.9em;}
117
45
 
118
- .required label, label[required], label.required, .has-error {color: red !important;}
119
- .required label:after, label[required]:after, label.required:after { content: '* '}
120
46
  textarea {width: 99%;}
121
47
 
122
48
  #internal_static_page_sign {
@@ -142,29 +68,7 @@ textarea {width: 99%;}
142
68
  }
143
69
  }
144
70
  }
145
- td.price {
146
- text-align: right;
147
- }
148
- table.table {
149
- th a.asc {
150
- &:after {
151
- content: "\2191";
152
- }
153
- }
154
- th a.desc {
155
- &:after {
156
- content: "\2193";
157
- }
158
- }
159
- tr.status {
160
- &--lock, &--inactive, &--archived {
161
- @include inactive-row;
162
- }
163
- }
164
- .buttons {
165
- text-align: right;
166
- }
167
- }
71
+
168
72
 
169
73
  .highlight {
170
74
  animation-duration: 1s;
@@ -1,13 +1,11 @@
1
1
  #symphonia_query_options_form {
2
2
  .filter-custom-date {
3
- &>* {
3
+ & > * {
4
4
  width: 49%;
5
- //&:last-child {
6
- // float:right;
7
- //}
8
5
  }
9
6
  }
10
7
  }
8
+
11
9
  #query_data {
12
10
  table.table {
13
11
  .price {
@@ -16,4 +14,4 @@
16
14
  }
17
15
  }
18
16
  }
19
- }
17
+ }
@@ -1,2 +1,2 @@
1
1
  @import "layout";
2
- @import "bootstrap-datepicker3";
2
+ // @import "bootstrap-datepicker3";
@@ -48,7 +48,7 @@ module Symphonia
48
48
  @user.attributes = user_params
49
49
  respond_to do |format|
50
50
  @user.edited_by = User.current.logged_in? && User.current
51
- @user.edited_at = Time.now
51
+ @user.edited_at = Time.current
52
52
  if @user.save
53
53
  format.html { redirect_to({ action: 'show' }, notice: t(:text_updated)) }
54
54
  format.json { head :no_content }
@@ -104,7 +104,7 @@ module Symphonia
104
104
  @user = find_account_by_token(params.require(:id))
105
105
  return render_404 if @user.nil?
106
106
 
107
- if params[:password] # && params[:password_confirmation]
107
+ if params[:password].present?
108
108
  @user.password = params[:password]
109
109
  end
110
110
 
@@ -147,8 +147,12 @@ module Symphonia
147
147
  User.current
148
148
  end
149
149
 
150
+ def current_ability
151
+ @current_ability ||= UserAbility.new current_user
152
+ end
153
+
150
154
  def find_account_by_mail(mail)
151
- User.where(email: mail).first
155
+ User.find_by(email: mail)
152
156
  end
153
157
 
154
158
  def find_account_by_token(id)
@@ -4,5 +4,6 @@ module Symphonia
4
4
  include ControllerExtensions
5
5
 
6
6
  helper Symphonia::BootstrapModalHelper
7
+
7
8
  end
8
- end
9
+ end
@@ -2,10 +2,10 @@ module Symphonia
2
2
  class UsersController < ApplicationController
3
3
 
4
4
  helper Symphonia::RendererHelper
5
+ include ::CanCan::ControllerAdditions
5
6
 
6
- before_action :find_user, except: %i[index new create show]
7
+ before_action :user, except: %i[index new create show]
7
8
  before_action :authorize, except: [:show]
8
- before_action -> { menu_item(:my_account) }, only: %i[current edit_current update_current]
9
9
 
10
10
  def index
11
11
  @query = Symphonia::User.query.new
@@ -22,8 +22,8 @@ module Symphonia
22
22
 
23
23
  def show
24
24
  @user = Symphonia::User.find(params[:id]) if params[:id]
25
- @user ||= Symphonia::User.current
26
- authorize
25
+ @user ||= current_user
26
+ authorize! :show, @user
27
27
  respond_to do |format|
28
28
  format.html
29
29
  format.json { render json: @user, except: %w[crypted_password password_salt persistence_token perishable_token] }
@@ -32,7 +32,6 @@ module Symphonia
32
32
 
33
33
  def new
34
34
  @user = Symphonia::User.new
35
- @roles = Symphonia::Role.sorted
36
35
  respond_to do |format|
37
36
  format.html
38
37
  end
@@ -46,27 +45,18 @@ module Symphonia
46
45
  format.xml { render xml: @user, status: :created, location: @user }
47
46
  format.json { render json: @user, status: :created, location: @user }
48
47
  else
49
- format.html do
50
- @roles = Symphonia::Role.sorted
51
- render action: 'new'
52
- end
48
+ format.html { render action: 'new' }
53
49
  format.xml { render xml: @user.errors, status: :unprocessable_entity }
54
50
  format.json { render json: @user.errors, status: :unprocessable_entity }
55
51
  end
56
52
  end
57
53
  end
58
54
 
59
- def edit
60
- @roles = Role.all
61
- end
55
+ def edit; end
62
56
 
63
57
  def update
64
58
  @user.attributes = user_params
65
- @user.admin = params[:admin] if params[:admin] && Symphonia::User.current.admin?
66
- if params[:role_id].present? && Symphonia::User.current.admin?
67
- @role = Role.find(params[:role_id])
68
- @user.role = @role
69
- end
59
+ @user.admin = params[:admin] if params[:admin] && current_user.admin?
70
60
  respond_to do |format|
71
61
  @user.edited_by = current_user
72
62
  @user.edited_at = DateTime.now
@@ -74,10 +64,7 @@ module Symphonia
74
64
  format.html { redirect_back_or_default user_path(@user), notice: t(:text_updated) }
75
65
  format.any(:json, :xml) { head :no_content }
76
66
  else
77
- format.html do
78
- @roles = Symphonia::Role.sorted
79
- render action: 'edit'
80
- end
67
+ format.html { render action: 'edit' }
81
68
  format.xml { render xml: @user.errors, status: :unprocessable_entity }
82
69
  format.json { render json: @user.errors, status: :unprocessable_entity }
83
70
  end
@@ -114,22 +101,23 @@ module Symphonia
114
101
 
115
102
  private
116
103
 
117
- def find_user
118
- @user = Symphonia::User.find(params[:id])
104
+ def user
105
+ @user ||= Symphonia::User.find(params[:id])
119
106
  end
120
107
 
121
108
  def authorize
122
- if User.current.logged_in? && User.current.id == @user&.id
123
- true
124
- else
125
- super
126
- end
109
+ authorize! action_name.to_sym, @user
127
110
  end
128
111
 
129
112
  def user_params
130
113
  allowed = [:login, :first_name, :last_name, :password, :password_confirmation, :email, :mail, preference_ids: []]
131
- allowed.concat(%i[admin role_id]) if Symphonia::User.current.admin?
114
+ allowed << :admin if current_user.admin?
132
115
  params.require(:user).permit(allowed)
133
116
  end
117
+
118
+ def current_ability
119
+ @current_ability ||= UserAbility.new current_user
120
+ end
121
+
134
122
  end
135
123
  end