enju_leaf 1.1.4 → 1.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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