enju_leaf 1.1.4 → 1.2.0.beta.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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +3 -3
  3. data/app/assets/javascripts/autocomplete_agent.js +30 -0
  4. data/app/assets/javascripts/{menu.enju.js → enju.menu.js} +5 -0
  5. data/app/assets/javascripts/enju_leaf.js +3 -3
  6. data/app/assets/javascripts/portlets.js +2 -2
  7. data/app/assets/stylesheets/enju.css +52 -18
  8. data/app/assets/stylesheets/enju_leaf.css +2 -0
  9. data/app/controllers/concerns/enju_leaf/controller.rb +225 -0
  10. data/app/controllers/my_accounts_controller.rb +9 -7
  11. data/app/controllers/names_controller.rb +60 -0
  12. data/app/controllers/page_controller.rb +5 -4
  13. data/app/controllers/profiles_controller.rb +13 -4
  14. data/app/controllers/roles_controller.rb +11 -2
  15. data/app/controllers/user_export_files_controller.rb +13 -3
  16. data/app/controllers/user_groups_controller.rb +12 -3
  17. data/app/controllers/user_import_files_controller.rb +14 -4
  18. data/app/controllers/user_import_results_controller.rb +11 -1
  19. data/app/jobs/user_export_file_job.rb +7 -0
  20. data/app/jobs/user_import_file_job.rb +7 -0
  21. data/app/mailers/notifier.rb +0 -2
  22. data/app/models/concerns/calculate_stat.rb +35 -0
  23. data/app/models/concerns/enju_leaf/enju_user.rb +309 -0
  24. data/app/models/concerns/export_file.rb +19 -0
  25. data/app/models/concerns/import_file.rb +89 -0
  26. data/app/models/concerns/master_model.rb +38 -0
  27. data/app/models/profile.rb +2 -2
  28. data/app/models/user_export_file.rb +0 -2
  29. data/app/models/user_group.rb +0 -3
  30. data/app/models/user_import_file.rb +0 -1
  31. data/app/policies/application_policy.rb +53 -0
  32. data/app/policies/name_policy.rb +21 -0
  33. data/app/policies/profile_policy.rb +55 -0
  34. data/app/policies/role_policy.rb +21 -0
  35. data/app/policies/user_export_file_policy.rb +21 -0
  36. data/app/policies/user_group_policy.rb +22 -0
  37. data/app/policies/user_import_file_policy.rb +21 -0
  38. data/app/policies/user_import_result_policy.rb +21 -0
  39. data/app/views/devise/sessions/{new.mobile.erb → new.html+phone.erb} +0 -0
  40. data/app/views/layouts/{application.mobile.erb → application.html+phone.erb} +0 -0
  41. data/app/views/layouts/application.html.erb +2 -2
  42. data/app/views/layouts/devise/{passwords.mobile.erb → passwords.html+phone.erb} +0 -0
  43. data/app/views/layouts/devise/{sessions.mobile.erb → sessions.html+phone.erb} +0 -0
  44. data/app/views/my_accounts/{show.mobile.erb → show.html+phone.erb} +0 -0
  45. data/app/views/my_accounts/show.html.erb +3 -3
  46. data/app/views/names/_form.html.erb +41 -0
  47. data/app/views/names/edit.html.erb +6 -0
  48. data/app/views/names/index.html.erb +37 -0
  49. data/app/views/names/new.html.erb +5 -0
  50. data/app/views/names/show.html.erb +34 -0
  51. data/app/views/page/{403.mobile.erb → 403.html+phone.erb} +0 -0
  52. data/app/views/page/{404.mobile.erb → 404.html+phone.erb} +0 -0
  53. data/app/views/page/{500.mobile.erb → 500.html+phone.erb} +0 -0
  54. data/app/views/page/_footer.html+phone.erb +3 -0
  55. data/app/views/page/_footer.html.erb +3 -10
  56. data/app/views/page/{_index.mobile.erb → _index.html+phone.erb} +0 -0
  57. data/app/views/page/_menu.html.erb +1 -1
  58. data/app/views/page/{_mobile.mobile.erb → _mobile.html+phone.erb} +0 -0
  59. data/app/views/page/{_search_form.mobile.erb → _search_form.html+phone.erb} +0 -0
  60. data/app/views/page/_select_locale.html.erb +1 -1
  61. data/app/views/page/configuration.html.erb +1 -1
  62. data/app/views/page/{index.mobile.erb → index.html+phone.erb} +0 -0
  63. data/app/views/profiles/edit.html.erb +1 -1
  64. data/app/views/profiles/index.html.erb +5 -5
  65. data/app/views/profiles/{show.mobile.erb → show.html+phone.erb} +0 -0
  66. data/app/views/profiles/show.html.erb +9 -4
  67. data/app/views/roles/index.html.erb +2 -2
  68. data/app/views/roles/show.html.erb +1 -1
  69. data/app/views/user_groups/_form.html.erb +1 -1
  70. data/app/views/user_groups/index.html.erb +4 -4
  71. data/app/views/user_groups/show.html.erb +2 -2
  72. data/config/locales/translation_ja.yml +2 -2
  73. data/config/routes.rb +1 -4
  74. data/db/migrate/20151126005552_add_provider_to_identity.rb +5 -0
  75. data/db/migrate/20160627232219_add_most_recent_to_user_import_file_transitions.rb +9 -0
  76. data/db/migrate/20160627232316_add_most_recent_to_user_export_file_transitions.rb +9 -0
  77. data/lib/enju_leaf/engine.rb +4 -8
  78. data/lib/enju_leaf/helper.rb +1 -1
  79. data/lib/enju_leaf/version.rb +1 -1
  80. data/lib/enju_leaf.rb +0 -249
  81. data/lib/generators/enju_leaf/setup/setup_generator.rb +19 -26
  82. data/lib/generators/enju_leaf/setup/templates/config/initializers/enju_leaf.rb +1 -0
  83. data/lib/tasks/enju_leaf_tasks.rake +2 -2
  84. data/spec/controllers/profiles_controller_spec.rb +22 -12
  85. data/spec/controllers/user_export_files_controller_spec.rb +9 -10
  86. data/spec/controllers/user_groups_controller_spec.rb +9 -9
  87. data/spec/controllers/user_import_files_controller_spec.rb +6 -6
  88. data/spec/controllers/user_import_results_controller_spec.rb +3 -3
  89. data/spec/dummy/app/controllers/application_controller.rb +6 -7
  90. data/spec/dummy/app/models/user.rb +4 -5
  91. data/spec/dummy/config/application.rb +6 -38
  92. data/spec/dummy/config/environments/development.rb +22 -18
  93. data/spec/dummy/config/environments/production.rb +46 -34
  94. data/spec/dummy/config/environments/test.rb +19 -14
  95. data/spec/dummy/config/initializers/enju_leaf.rb +2 -0
  96. data/spec/dummy/config/routes.rb +5 -1
  97. data/spec/dummy/db/migrate/20151213070943_add_translation_table_to_library_group.rb +13 -0
  98. data/spec/dummy/db/migrate/20151213072705_add_footer_banner_to_library_group.rb +9 -0
  99. data/spec/dummy/db/schema.rb +15 -0
  100. data/spec/factories/profile.rb +6 -6
  101. data/spec/models/user_export_file_spec.rb +1 -1
  102. data/spec/models/user_import_file_spec.rb +5 -5
  103. data/spec/rails_helper.rb +4 -11
  104. data/spec/routing/users_spec.rb +14 -0
  105. data/spec/spec_helper.rb +1 -1
  106. data/spec/support/devise.rb +2 -2
  107. data/spec/views/my_accounts/show.html.erb_spec.rb +43 -0
  108. data/spec/views/page/about.html.erb_spec.rb +0 -3
  109. data/spec/views/page/advanced_search.html.erb_spec.rb +1 -4
  110. data/spec/views/page/configuration.html.erb_spec.rb +0 -3
  111. data/spec/views/page/export.html.erb_spec.rb +0 -3
  112. data/spec/views/page/import.html.erb_spec.rb +0 -3
  113. data/spec/views/page/index.html.erb_spec.rb +1 -4
  114. data/spec/views/page/opensearch.xml.builder_spec.rb +1 -4
  115. data/spec/views/page/statistics.html.erb_spec.rb +0 -3
  116. data/spec/views/profiles/edit.html.erb_spec.rb +11 -14
  117. data/spec/views/profiles/index.html.erb_spec.rb +3 -4
  118. data/spec/views/profiles/show.html.erb_spec.rb +3 -8
  119. data/spec/views/user_import_results/index.html.erb_spec.rb +0 -3
  120. data/vendor/assets/javascripts/jquery.highlight.js +97 -56
  121. metadata +114 -288
  122. data/app/assets/javascripts/tab_view.js +0 -4
  123. data/app/models/enju_leaf/ability.rb +0 -102
  124. data/app/views/page/_footer.mobile.erb +0 -3
  125. data/app/workers/user_export_file_queue.rb +0 -7
  126. data/app/workers/user_import_file_queue.rb +0 -7
  127. data/config/initializers/resque.rb +0 -1
  128. data/lib/enju_leaf/calculate_stat.rb +0 -42
  129. data/lib/enju_leaf/controller.rb +0 -24
  130. data/lib/enju_leaf/export_file.rb +0 -26
  131. data/lib/enju_leaf/import_file.rb +0 -99
  132. data/lib/enju_leaf/master_model.rb +0 -42
  133. data/lib/enju_leaf/user.rb +0 -317
  134. data/lib/plugins/ext/mobylette/resolvers/chained_fallback_resolver.rb +0 -73
  135. data/lib/plugins/ext/mobylette.rb +0 -2
  136. data/lib/plugins/ext/sunspot/abstract_search.rb +0 -12
  137. data/lib/plugins/ext/sunspot/dismax.rb +0 -41
  138. data/lib/plugins/ext/sunspot/start_record.rb +0 -55
  139. data/lib/plugins/ext/sunspot.rb +0 -3
  140. data/lib/plugins/ext.rb +0 -2
  141. data/lib/plugins.rb +0 -2
  142. data/spec/dummy/config/application.yml +0 -47
  143. data/spec/routing/accounts_spec.rb +0 -14
@@ -1,7 +1,7 @@
1
- # -*- encoding: utf-8 -*-
2
1
  class UserGroupsController < ApplicationController
3
- load_and_authorize_resource
4
- before_filter :prepare_options, only: [:new, :edit]
2
+ before_action :set_user_group, only: [:show, :edit, :update, :destroy]
3
+ before_action :check_policy, only: [:index, :new, :create]
4
+ before_action :prepare_options, only: [:new, :edit]
5
5
 
6
6
  # GET /user_groups
7
7
  # GET /user_groups.json
@@ -86,6 +86,15 @@ class UserGroupsController < ApplicationController
86
86
  end
87
87
 
88
88
  private
89
+ def set_user_group
90
+ @user_group = UserGroup.find(params[:id])
91
+ authorize @user_group
92
+ end
93
+
94
+ def check_policy
95
+ authorize UserGroup
96
+ end
97
+
89
98
  def user_group_params
90
99
  params.require(:user_group).permit(
91
100
  :name, :display_name, :note, :valid_period_for_new_user,
@@ -1,6 +1,7 @@
1
1
  class UserImportFilesController < ApplicationController
2
- load_and_authorize_resource
3
- before_filter :prepare_options, only: [:new, :edit]
2
+ before_action :set_user_import_file, only: [:show, :edit, :update, :destroy]
3
+ before_action :check_policy, only: [:index, :new, :create]
4
+ before_action :prepare_options, only: [:new, :edit]
4
5
 
5
6
  # GET /user_import_files
6
7
  # GET /user_import_files.json
@@ -63,7 +64,7 @@ class UserImportFilesController < ApplicationController
63
64
  respond_to do |format|
64
65
  if @user_import_file.save
65
66
  if @user_import_file.mode == 'import'
66
- Resque.enqueue(UserImportFileQueue, @user_import_file.id)
67
+ UserImportFileJob.perform_later(@user_import_file)
67
68
  end
68
69
  format.html { redirect_to @user_import_file, notice: t('import.successfully_created', model: t('activerecord.models.user_import_file')) }
69
70
  format.json { render json: @user_import_file, status: :created, location: @user_import_file }
@@ -81,7 +82,7 @@ class UserImportFilesController < ApplicationController
81
82
  respond_to do |format|
82
83
  if @user_import_file.update_attributes(user_import_file_params)
83
84
  if @user_import_file.mode == 'import'
84
- Resque.enqueue(UserImportFileQueue, @user_import_file.id)
85
+ UserImportFileJob.perform_later(@user_import_file)
85
86
  end
86
87
  format.html { redirect_to @user_import_file, notice: t('controller.successfully_updated', model: t('activerecord.models.user_import_file')) }
87
88
  format.json { head :no_content }
@@ -105,6 +106,15 @@ class UserImportFilesController < ApplicationController
105
106
  end
106
107
 
107
108
  private
109
+ def set_user_import_file
110
+ @user_import_file = UserImportFile.find(params[:id])
111
+ authorize @user_import_file
112
+ end
113
+
114
+ def check_policy
115
+ authorize UserImportFile
116
+ end
117
+
108
118
  def user_import_file_params
109
119
  params.require(:user_import_file).permit(
110
120
  :user_import, :edit_mode, :user_encoding, :mode,
@@ -1,5 +1,6 @@
1
1
  class UserImportResultsController < ApplicationController
2
- load_and_authorize_resource
2
+ before_action :set_user_import_result, only: [:show, :edit, :update, :destroy]
3
+ before_action :check_policy, only: [:index, :new, :create]
3
4
 
4
5
  # GET /user_import_results
5
6
  # GET /user_import_results.json
@@ -39,6 +40,15 @@ class UserImportResultsController < ApplicationController
39
40
  end
40
41
 
41
42
  private
43
+ def set_user_import_result
44
+ @user_import_result = UserImportResult.find(params[:id])
45
+ authorize @user_import_result
46
+ end
47
+
48
+ def check_policy
49
+ authorize UserImportResult
50
+ end
51
+
42
52
  def user_import_result_params
43
53
  params.require(:user_import_result).permit(
44
54
  :user_import_file_id, :user_id, :body
@@ -0,0 +1,7 @@
1
+ class UserExportFileJob < ActiveJob::Base
2
+ queue_as :enju_leaf
3
+
4
+ def perform(user_export_file)
5
+ user_export_file.export!
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class UserImportFileJob < ActiveJob::Base
2
+ queue_as :enju_leaf
3
+
4
+ def perform(user_import_file)
5
+ user_import_file.import_start
6
+ end
7
+ end
@@ -1,6 +1,4 @@
1
1
  class Notifier < ActionMailer::Base
2
- include Resque::Mailer
3
-
4
2
  def message_notification(message_id)
5
3
  message = Message.find(message_id)
6
4
  I18n.locale = message.receiver.profile.locale.try(:to_sym) || I18n.default_locale
@@ -0,0 +1,35 @@
1
+ module CalculateStat
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ validates_presence_of :start_date, :end_date
6
+ validate :check_date
7
+
8
+ # 利用統計の集計を開始します。
9
+ def self.calculate_stat
10
+ self.not_calculated.each do |stat|
11
+ stat.transition_to!(:started)
12
+ end
13
+ end
14
+ end
15
+
16
+ # 利用統計の日付をチェックします。
17
+ def check_date
18
+ if self.start_date and self.end_date
19
+ if self.start_date >= self.end_date
20
+ errors.add(:start_date)
21
+ errors.add(:end_date)
22
+ end
23
+ end
24
+ end
25
+
26
+ # 利用統計の集計完了メッセージを送信します。
27
+ def send_message
28
+ sender = User.find(1) #system
29
+ message_template = MessageTemplate.localized_template('counting_completed', user.profile.locale)
30
+ request = MessageRequest.new
31
+ request.assign_attributes({sender: sender, receiver: user, message_template: message_template})
32
+ request.save_message_body
33
+ request.transition_to!(:sent)
34
+ end
35
+ end
@@ -0,0 +1,309 @@
1
+ module EnjuLeaf
2
+ module EnjuUser
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ scope :administrators, -> { joins(:role).where('roles.name = ?', 'Administrator') }
7
+ scope :librarians, -> { joins(:role).where('roles.name = ? OR roles.name = ?', 'Administrator', 'Librarian') }
8
+ scope :suspended, -> { where('locked_at IS NOT NULL') }
9
+ has_one :profile
10
+ if defined?(EnjuBiblio)
11
+ has_many :import_requests
12
+ has_many :picture_files, as: :picture_attachable, dependent: :destroy
13
+ end
14
+ has_one :user_has_role, dependent: :destroy
15
+ has_one :role, through: :user_has_role
16
+ belongs_to :user_group
17
+ belongs_to :library
18
+ belongs_to :required_role, class_name: 'Role', foreign_key: 'required_role_id'
19
+ accepts_nested_attributes_for :user_has_role
20
+
21
+ validates :username, presence: true, uniqueness: true, format: {
22
+ with: /\A[0-9A-Za-z][0-9A-Za-z_\-]*[0-9A-Za-z]\z/
23
+ }
24
+ validates :email, format: Devise::email_regexp, allow_blank: true, uniqueness: true
25
+ validates_date :expired_at, allow_blank: true
26
+
27
+ with_options if: :password_required? do |v|
28
+ v.validates_presence_of :password
29
+ v.validates_confirmation_of :password
30
+ v.validates_length_of :password, allow_blank: true,
31
+ within: Devise::password_length
32
+ end
33
+
34
+ before_validation :set_lock_information
35
+ before_destroy :check_role_before_destroy
36
+ before_save :check_expiration
37
+ after_create :set_confirmation
38
+
39
+ extend FriendlyId
40
+ friendly_id :username
41
+ strip_attributes only: :username
42
+ strip_attributes only: :email, allow_empty: true
43
+
44
+ attr_accessor :password_not_verified,
45
+ :update_own_account, :auto_generated_password,
46
+ :locked, :current_password #, :agent_id
47
+
48
+ paginates_per 10
49
+
50
+ def send_devise_notification(notification, *args)
51
+ devise_mailer.send(notification, self, *args).deliver_later
52
+ end
53
+
54
+ # 有効期限切れのユーザを一括で使用不可にします。
55
+ def self.lock_expired_users
56
+ User.find_each do |user|
57
+ user.lock_access! if user.expired? and user.active_for_authentication?
58
+ end
59
+ end
60
+
61
+ # ユーザの情報をエクスポートします。
62
+ # @param [Hash] options
63
+ def self.export(options = {format: :txt})
64
+ header = %w(
65
+ username
66
+ full_name
67
+ full_name_transcription
68
+ email
69
+ user_number
70
+ role
71
+ user_group
72
+ library
73
+ locale
74
+ locked
75
+ required_role
76
+ created_at
77
+ updated_at
78
+ expired_at
79
+ keyword_list
80
+ note
81
+ )
82
+ header += %w(
83
+ checkout_icalendar_token
84
+ save_checkout_history
85
+ ) if defined? EnjuCirculation
86
+ header << "save_search_history" if defined? EnjuSearchLog
87
+ header << "share_bookmarks" if defined? EnjuBookmark
88
+ lines = []
89
+ User.find_each.map{|u|
90
+ line = []
91
+ line << u.username
92
+ line << u.try(:profile).try(:full_name)
93
+ line << u.try(:profile).try(:full_name_transcription)
94
+ line << u.email
95
+ line << u.try(:profile).try(:user_number)
96
+ line << u.role.try(:name)
97
+ line << u.try(:profile).try(:user_group).try(:name)
98
+ line << u.try(:profile).try(:library).try(:name)
99
+ line << u.try(:profile).try(:locale)
100
+ line << u.access_locked?
101
+ line << u.try(:profile).try(:required_role).try(:name)
102
+ line << u.created_at
103
+ line << u.updated_at
104
+ line << u.try(:profile).try(:expired_at)
105
+ line << u.try(:profile).try(:keyword_list).try(:split).try(:join, "//")
106
+ line << u.try(:profile).try(:note)
107
+ if defined? EnjuCirculation
108
+ line << u.try(:profile).try(:checkout_icalendar_token)
109
+ line << u.try(:profile).try(:save_checkout_history)
110
+ end
111
+ if defined? EnjuSearchLog
112
+ line << u.try(:profile).try(:save_search_history)
113
+ end
114
+ if defined? EnjuBookmark
115
+ line << u.try(:profile).try(:share_bookmarks)
116
+ end
117
+ lines << line
118
+ }
119
+ if options[:format] == :txt
120
+ lines.map{|line| line.to_csv(col_sep: "\t")}.unshift(header.to_csv(col_sep: "\t")).join
121
+ else
122
+ lines
123
+ end
124
+ end
125
+ end
126
+
127
+ # ユーザにパスワードが必要かどうかをチェックします。
128
+ # @return [Boolean]
129
+ def password_required?
130
+ if Devise.mappings[:user].modules.include?(:database_authenticatable)
131
+ !persisted? || !password.nil? || !password_confirmation.nil?
132
+ end
133
+ end
134
+
135
+ # ユーザが特定の権限を持っているかどうかをチェックします。
136
+ # @param [String] role_in_question 権限名
137
+ # @return [Boolean]
138
+ def has_role?(role_in_question)
139
+ return false unless role
140
+ return true if role.name == role_in_question
141
+ case role.name
142
+ when 'Administrator'
143
+ return true
144
+ when 'Librarian'
145
+ return true if role_in_question == 'User'
146
+ else
147
+ false
148
+ end
149
+ end
150
+
151
+ # ユーザに使用不可の設定を反映させます。
152
+ def set_lock_information
153
+ if locked == '1' and self.active_for_authentication?
154
+ lock_access!
155
+ elsif locked == '0' and !self.active_for_authentication?
156
+ unlock_access!
157
+ end
158
+ end
159
+
160
+ def set_confirmation
161
+ if respond_to?(:confirm!)
162
+ reload
163
+ confirm!
164
+ end
165
+ end
166
+
167
+ # ユーザが有効期限切れかどうかをチェックし、期限切れであれば使用不可に設定します。
168
+ # @return [Object]
169
+ def check_expiration
170
+ return if has_role?('Administrator')
171
+ if expired_at
172
+ if expired_at.beginning_of_day < Time.zone.now.beginning_of_day
173
+ lock_access! if active_for_authentication?
174
+ end
175
+ end
176
+ end
177
+
178
+ # ユーザの削除前に、管理者ユーザが不在にならないかどうかをチェックします。
179
+ # @return [Object]
180
+ def check_role_before_destroy
181
+ if has_role?('Administrator')
182
+ if Role.where(name: 'Administrator').first.users.count == 1
183
+ raise username + 'This is the last administrator in this system.'
184
+ end
185
+ end
186
+ end
187
+
188
+ # ユーザに自動生成されたパスワードを設定します。
189
+ # @return [String]
190
+ def set_auto_generated_password
191
+ password = Devise.friendly_token[0..7]
192
+ self.password = password
193
+ self.password_confirmation = password
194
+ end
195
+
196
+ # ユーザが有効期限切れかどうかをチェックします。
197
+ # @return [Boolean]
198
+ def expired?
199
+ if expired_at
200
+ true if expired_at.beginning_of_day < Time.zone.now.beginning_of_day
201
+ end
202
+ end
203
+
204
+ # ユーザが管理者かどうかをチェックします。
205
+ # @return [Boolean]
206
+ def is_admin?
207
+ return true if has_role?('Administrator')
208
+ false
209
+ end
210
+
211
+ # ユーザがシステム上の最後のLibrarian権限ユーザかどうかをチェックします。
212
+ # @return [Boolean]
213
+ def last_librarian?
214
+ if has_role?('Librarian')
215
+ role = Role.where(name: 'Librarian').first
216
+ return true if role.users.count == 1
217
+ false
218
+ end
219
+ end
220
+
221
+ def send_confirmation_instructions
222
+ Devise::Mailer.confirmation_instructions(self).deliver if email.present?
223
+ end
224
+
225
+ # ユーザが削除可能かどうかをチェックします。
226
+ # @param [User] current_user ユーザ
227
+ # @return [Object]
228
+ def deletable_by?(current_user)
229
+ return nil unless current_user
230
+ if defined?(EnjuCirculation)
231
+ # 未返却の資料のあるユーザを削除しようとした
232
+ if checkouts.count > 0
233
+ errors[:base] << I18n.t('user.this_user_has_checked_out_item')
234
+ end
235
+ end
236
+
237
+ if has_role?('Librarian')
238
+ # 管理者以外のユーザが図書館員を削除しようとした。図書館員の削除は管理者しかできない
239
+ unless current_user.has_role?('Administrator')
240
+ errors[:base] << I18n.t('user.only_administrator_can_destroy')
241
+ end
242
+ # 最後の図書館員を削除しようとした
243
+ if last_librarian?
244
+ errors[:base] << I18n.t('user.last_librarian')
245
+ end
246
+ end
247
+
248
+ # 最後の管理者を削除しようとした
249
+ if has_role?('Administrator')
250
+ if Role.where(name: 'Administrator').first.users.count == 1
251
+ errors[:base] << I18n.t('user.last_administrator')
252
+ end
253
+ end
254
+
255
+ if errors[:base] == []
256
+ true
257
+ else
258
+ false
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+
265
+ # == Schema Information
266
+ #
267
+ # Table name: users
268
+ #
269
+ # id :integer not null, primary key
270
+ # email :string(255) default(""), not null
271
+ # encrypted_password :string(255) default(""), not null
272
+ # reset_password_token :string(255)
273
+ # reset_password_sent_at :datetime
274
+ # remember_created_at :datetime
275
+ # sign_in_count :integer default(0)
276
+ # current_sign_in_at :datetime
277
+ # last_sign_in_at :datetime
278
+ # current_sign_in_ip :string(255)
279
+ # last_sign_in_ip :string(255)
280
+ # password_salt :string(255)
281
+ # confirmation_token :string(255)
282
+ # confirmed_at :datetime
283
+ # confirmation_sent_at :datetime
284
+ # unconfirmed_email :string(255)
285
+ # failed_attempts :integer default(0)
286
+ # unlock_token :string(255)
287
+ # locked_at :datetime
288
+ # authentication_token :string(255)
289
+ # created_at :datetime not null
290
+ # updated_at :datetime not null
291
+ # deleted_at :datetime
292
+ # username :string(255) not null
293
+ # library_id :integer default(1), not null
294
+ # user_group_id :integer default(1), not null
295
+ # expired_at :datetime
296
+ # required_role_id :integer default(1), not null
297
+ # note :text
298
+ # keyword_list :text
299
+ # user_number :string(255)
300
+ # state :string(255)
301
+ # locale :string(255)
302
+ # enju_access_key :string(255)
303
+ # save_checkout_history :boolean
304
+ # checkout_icalendar_token :string(255)
305
+ # share_bookmarks :boolean
306
+ # save_search_history :boolean
307
+ # answer_feed_token :string(255)
308
+ #
309
+
@@ -0,0 +1,19 @@
1
+ module ExportFile
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to :user
6
+ validates :user, presence: true
7
+ attr_accessor :mode
8
+ end
9
+
10
+ def send_message
11
+ sender = User.find(1) #system
12
+ locale = user.profile.try(:locale) || I18n.default_locale.to_s
13
+ message_template = MessageTemplate.localized_template('export_completed', locale)
14
+ request = MessageRequest.new
15
+ request.assign_attributes({sender: sender, receiver: user, message_template: message_template})
16
+ request.save_message_body
17
+ request.transition_to!(:sent)
18
+ end
19
+ end
@@ -0,0 +1,89 @@
1
+ module ImportFile
2
+ extend ActiveSupport::Concern
3
+
4
+ # 失敗したインポート処理を一括削除します。
5
+ def self.expire
6
+ self.stucked.find_each do |file|
7
+ file.destroy
8
+ end
9
+ end
10
+
11
+ def import_start
12
+ case edit_mode
13
+ when 'create'
14
+ import
15
+ when 'update'
16
+ modify
17
+ when 'destroy'
18
+ remove
19
+ else
20
+ import
21
+ end
22
+ end
23
+
24
+ # インポートするファイルの文字コードをUTF-8に変換します。
25
+ # @param [String] line 変換する文字列
26
+ def convert_encoding(line)
27
+ if defined?(CharlockHolmes::EncodingDetector)
28
+ begin
29
+ case user_encoding
30
+ when 'auto_detect'
31
+ encoding = CharlockHolmes::EncodingDetector.detect(line)[:encoding]
32
+ when nil
33
+ encoding = CharlockHolmes::EncodingDetector.detect(line)[:encoding]
34
+ else
35
+ encoding = user_encoding
36
+ end
37
+ line.encode('UTF-8', encoding, universal_newline: true)
38
+ rescue StandardError
39
+ nkf_encode(line)
40
+ end
41
+ else
42
+ nkf_encode(line)
43
+ end
44
+ end
45
+
46
+ # インポート完了時のメッセージを送信します。
47
+ def send_message
48
+ sender = User.find(1)
49
+ locale = user.profile.try(:locale) || I18n.default_locale.to_s
50
+ message_template = MessageTemplate.localized_template('import_completed', locale)
51
+ request = MessageRequest.new
52
+ request.assign_attributes({sender: sender, receiver: user, message_template: message_template})
53
+ request.save_message_body
54
+ request.transition_to!(:sent)
55
+ end
56
+
57
+ private
58
+ def nkf_encode(line)
59
+ case user_encoding
60
+ when 'auto_detect'
61
+ output_encoding = '-w'
62
+ when 'UTF-8'
63
+ output_encoding = ''
64
+ when 'Shift_JIS'
65
+ output_encoding = '-Sw'
66
+ when 'EUC-JP'
67
+ output_encoding = '-Ew'
68
+ else
69
+ output_encoding = '-w'
70
+ end
71
+ NKF.nkf("#{output_encoding} -Lu", line)
72
+ end
73
+
74
+ def create_import_temp_file(attachment)
75
+ tempfile = Tempfile.new(self.class.name.underscore)
76
+ if ENV['ENJU_STORAGE'] == 's3'
77
+ tempfile.write Faraday.get(attachment.expiring_url(10)).body.force_encoding('UTF-8')
78
+ else
79
+ uploaded_file_path = attachment.path
80
+ open(uploaded_file_path){|f|
81
+ f.each{|line|
82
+ tempfile.puts(convert_encoding(line))
83
+ }
84
+ }
85
+ end
86
+ tempfile.close
87
+ tempfile
88
+ end
89
+ end
@@ -0,0 +1,38 @@
1
+ module MasterModel
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ acts_as_list
6
+ validates_uniqueness_of :name, case_sensitive: false
7
+ validates :name, presence: true
8
+ validate :name do
9
+ valid_name?
10
+ end
11
+ validate :display_name do
12
+ valid_yaml?
13
+ end
14
+ validates :display_name, presence: true
15
+ before_validation :set_display_name, on: :create
16
+ strip_attributes only: :name
17
+ end
18
+
19
+ # 表示名を設定します。
20
+ def set_display_name
21
+ self.display_name = "#{I18n.locale}: #{name}" if display_name.blank?
22
+ end
23
+
24
+ private
25
+ def valid_name?
26
+ unless name =~ /\A[a-z][0-9a-z_]*[0-9a-z]\z/
27
+ errors.add(:name, I18n.t('page.only_lowercase_letters_and_numbers_are_allowed'))
28
+ end
29
+ end
30
+
31
+ def valid_yaml?
32
+ begin
33
+ YAML.load(display_name)
34
+ rescue Psych::SyntaxError
35
+ errors.add(:display_name, I18n.t('page.cannot_parse_yaml_header'))
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,4 @@
1
1
  class Profile < ActiveRecord::Base
2
- enju_circulation_profile_model if defined?(EnjuCirculation)
3
2
  enju_search_log_profile_model if defined?(EnjuSearchLog)
4
3
 
5
4
  scope :administrators, -> { joins(user: :role).where('roles.name = ?', 'Administrator') }
@@ -9,6 +8,7 @@ class Profile < ActiveRecord::Base
9
8
  belongs_to :user_group
10
9
  belongs_to :required_role, class_name: 'Role', foreign_key: 'required_role_id' #, validate: true
11
10
  has_many :identities
11
+ has_many :agents
12
12
  accepts_nested_attributes_for :identities, allow_destroy: true, reject_if: :all_blank
13
13
 
14
14
  validates_associated :user_group, :library
@@ -18,7 +18,7 @@ class Profile < ActiveRecord::Base
18
18
  validates :user_id, uniqueness: true, allow_blank: true
19
19
  validates :birth_date, format: { with: /\A\d{4}-\d{1,2}-\d{1,2}\z/ }, allow_blank: true
20
20
 
21
- normalize_attribute :user_number
21
+ strip_attributes only: :user_number
22
22
 
23
23
  attr_accessor :birth_date
24
24
 
@@ -1,7 +1,6 @@
1
1
  class UserExportFile < ActiveRecord::Base
2
2
  include Statesman::Adapters::ActiveRecordQueries
3
3
  include ExportFile
4
- enju_export_file_model
5
4
 
6
5
  if ENV['ENJU_STORAGE'] == 's3'
7
6
  has_attached_file :user_export, storage: :s3,
@@ -44,7 +43,6 @@ class UserExportFile < ActiveRecord::Base
44
43
  raise e
45
44
  end
46
45
 
47
- private
48
46
  def self.transition_class
49
47
  UserExportFileTransition
50
48
  end
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  class UserGroup < ActiveRecord::Base
3
2
  include MasterModel
4
3
  has_many :profiles
@@ -8,8 +7,6 @@ class UserGroup < ActiveRecord::Base
8
7
  allow_blank: true
9
8
 
10
9
  paginates_per 10
11
-
12
- enju_circulation_user_group_model if defined?(EnjuCirculation)
13
10
  end
14
11
 
15
12
  # == Schema Information
@@ -33,7 +33,6 @@ class UserImportFile < ActiveRecord::Base
33
33
 
34
34
  has_many :user_import_file_transitions
35
35
 
36
- enju_import_file_model
37
36
  attr_accessor :mode
38
37
 
39
38
  def state_machine