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.
- checksums.yaml +4 -4
- data/README.rdoc +3 -3
- data/app/assets/javascripts/autocomplete_agent.js +30 -0
- data/app/assets/javascripts/{menu.enju.js → enju.menu.js} +5 -0
- data/app/assets/javascripts/enju_leaf.js +3 -3
- data/app/assets/javascripts/portlets.js +2 -2
- data/app/assets/stylesheets/enju.css +52 -18
- data/app/assets/stylesheets/enju_leaf.css +2 -0
- data/app/controllers/concerns/enju_leaf/controller.rb +225 -0
- data/app/controllers/my_accounts_controller.rb +9 -7
- data/app/controllers/names_controller.rb +60 -0
- data/app/controllers/page_controller.rb +5 -4
- data/app/controllers/profiles_controller.rb +13 -4
- data/app/controllers/roles_controller.rb +11 -2
- data/app/controllers/user_export_files_controller.rb +13 -3
- data/app/controllers/user_groups_controller.rb +12 -3
- data/app/controllers/user_import_files_controller.rb +14 -4
- data/app/controllers/user_import_results_controller.rb +11 -1
- data/app/jobs/user_export_file_job.rb +7 -0
- data/app/jobs/user_import_file_job.rb +7 -0
- data/app/mailers/notifier.rb +0 -2
- data/app/models/concerns/calculate_stat.rb +35 -0
- data/app/models/concerns/enju_leaf/enju_user.rb +309 -0
- data/app/models/concerns/export_file.rb +19 -0
- data/app/models/concerns/import_file.rb +89 -0
- data/app/models/concerns/master_model.rb +38 -0
- data/app/models/profile.rb +2 -2
- data/app/models/user_export_file.rb +0 -2
- data/app/models/user_group.rb +0 -3
- data/app/models/user_import_file.rb +0 -1
- data/app/policies/application_policy.rb +53 -0
- data/app/policies/name_policy.rb +21 -0
- data/app/policies/profile_policy.rb +55 -0
- data/app/policies/role_policy.rb +21 -0
- data/app/policies/user_export_file_policy.rb +21 -0
- data/app/policies/user_group_policy.rb +22 -0
- data/app/policies/user_import_file_policy.rb +21 -0
- data/app/policies/user_import_result_policy.rb +21 -0
- data/app/views/devise/sessions/{new.mobile.erb → new.html+phone.erb} +0 -0
- data/app/views/layouts/{application.mobile.erb → application.html+phone.erb} +0 -0
- data/app/views/layouts/application.html.erb +2 -2
- data/app/views/layouts/devise/{passwords.mobile.erb → passwords.html+phone.erb} +0 -0
- data/app/views/layouts/devise/{sessions.mobile.erb → sessions.html+phone.erb} +0 -0
- data/app/views/my_accounts/{show.mobile.erb → show.html+phone.erb} +0 -0
- data/app/views/my_accounts/show.html.erb +3 -3
- data/app/views/names/_form.html.erb +41 -0
- data/app/views/names/edit.html.erb +6 -0
- data/app/views/names/index.html.erb +37 -0
- data/app/views/names/new.html.erb +5 -0
- data/app/views/names/show.html.erb +34 -0
- data/app/views/page/{403.mobile.erb → 403.html+phone.erb} +0 -0
- data/app/views/page/{404.mobile.erb → 404.html+phone.erb} +0 -0
- data/app/views/page/{500.mobile.erb → 500.html+phone.erb} +0 -0
- data/app/views/page/_footer.html+phone.erb +3 -0
- data/app/views/page/_footer.html.erb +3 -10
- data/app/views/page/{_index.mobile.erb → _index.html+phone.erb} +0 -0
- data/app/views/page/_menu.html.erb +1 -1
- data/app/views/page/{_mobile.mobile.erb → _mobile.html+phone.erb} +0 -0
- data/app/views/page/{_search_form.mobile.erb → _search_form.html+phone.erb} +0 -0
- data/app/views/page/_select_locale.html.erb +1 -1
- data/app/views/page/configuration.html.erb +1 -1
- data/app/views/page/{index.mobile.erb → index.html+phone.erb} +0 -0
- data/app/views/profiles/edit.html.erb +1 -1
- data/app/views/profiles/index.html.erb +5 -5
- data/app/views/profiles/{show.mobile.erb → show.html+phone.erb} +0 -0
- data/app/views/profiles/show.html.erb +9 -4
- data/app/views/roles/index.html.erb +2 -2
- data/app/views/roles/show.html.erb +1 -1
- data/app/views/user_groups/_form.html.erb +1 -1
- data/app/views/user_groups/index.html.erb +4 -4
- data/app/views/user_groups/show.html.erb +2 -2
- data/config/locales/translation_ja.yml +2 -2
- data/config/routes.rb +1 -4
- data/db/migrate/20151126005552_add_provider_to_identity.rb +5 -0
- data/db/migrate/20160627232219_add_most_recent_to_user_import_file_transitions.rb +9 -0
- data/db/migrate/20160627232316_add_most_recent_to_user_export_file_transitions.rb +9 -0
- data/lib/enju_leaf/engine.rb +4 -8
- data/lib/enju_leaf/helper.rb +1 -1
- data/lib/enju_leaf/version.rb +1 -1
- data/lib/enju_leaf.rb +0 -249
- data/lib/generators/enju_leaf/setup/setup_generator.rb +19 -26
- data/lib/generators/enju_leaf/setup/templates/config/initializers/enju_leaf.rb +1 -0
- data/lib/tasks/enju_leaf_tasks.rake +2 -2
- data/spec/controllers/profiles_controller_spec.rb +22 -12
- data/spec/controllers/user_export_files_controller_spec.rb +9 -10
- data/spec/controllers/user_groups_controller_spec.rb +9 -9
- data/spec/controllers/user_import_files_controller_spec.rb +6 -6
- data/spec/controllers/user_import_results_controller_spec.rb +3 -3
- data/spec/dummy/app/controllers/application_controller.rb +6 -7
- data/spec/dummy/app/models/user.rb +4 -5
- data/spec/dummy/config/application.rb +6 -38
- data/spec/dummy/config/environments/development.rb +22 -18
- data/spec/dummy/config/environments/production.rb +46 -34
- data/spec/dummy/config/environments/test.rb +19 -14
- data/spec/dummy/config/initializers/enju_leaf.rb +2 -0
- data/spec/dummy/config/routes.rb +5 -1
- data/spec/dummy/db/migrate/20151213070943_add_translation_table_to_library_group.rb +13 -0
- data/spec/dummy/db/migrate/20151213072705_add_footer_banner_to_library_group.rb +9 -0
- data/spec/dummy/db/schema.rb +15 -0
- data/spec/factories/profile.rb +6 -6
- data/spec/models/user_export_file_spec.rb +1 -1
- data/spec/models/user_import_file_spec.rb +5 -5
- data/spec/rails_helper.rb +4 -11
- data/spec/routing/users_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/devise.rb +2 -2
- data/spec/views/my_accounts/show.html.erb_spec.rb +43 -0
- data/spec/views/page/about.html.erb_spec.rb +0 -3
- data/spec/views/page/advanced_search.html.erb_spec.rb +1 -4
- data/spec/views/page/configuration.html.erb_spec.rb +0 -3
- data/spec/views/page/export.html.erb_spec.rb +0 -3
- data/spec/views/page/import.html.erb_spec.rb +0 -3
- data/spec/views/page/index.html.erb_spec.rb +1 -4
- data/spec/views/page/opensearch.xml.builder_spec.rb +1 -4
- data/spec/views/page/statistics.html.erb_spec.rb +0 -3
- data/spec/views/profiles/edit.html.erb_spec.rb +11 -14
- data/spec/views/profiles/index.html.erb_spec.rb +3 -4
- data/spec/views/profiles/show.html.erb_spec.rb +3 -8
- data/spec/views/user_import_results/index.html.erb_spec.rb +0 -3
- data/vendor/assets/javascripts/jquery.highlight.js +97 -56
- metadata +114 -288
- data/app/assets/javascripts/tab_view.js +0 -4
- data/app/models/enju_leaf/ability.rb +0 -102
- data/app/views/page/_footer.mobile.erb +0 -3
- data/app/workers/user_export_file_queue.rb +0 -7
- data/app/workers/user_import_file_queue.rb +0 -7
- data/config/initializers/resque.rb +0 -1
- data/lib/enju_leaf/calculate_stat.rb +0 -42
- data/lib/enju_leaf/controller.rb +0 -24
- data/lib/enju_leaf/export_file.rb +0 -26
- data/lib/enju_leaf/import_file.rb +0 -99
- data/lib/enju_leaf/master_model.rb +0 -42
- data/lib/enju_leaf/user.rb +0 -317
- data/lib/plugins/ext/mobylette/resolvers/chained_fallback_resolver.rb +0 -73
- data/lib/plugins/ext/mobylette.rb +0 -2
- data/lib/plugins/ext/sunspot/abstract_search.rb +0 -12
- data/lib/plugins/ext/sunspot/dismax.rb +0 -41
- data/lib/plugins/ext/sunspot/start_record.rb +0 -55
- data/lib/plugins/ext/sunspot.rb +0 -3
- data/lib/plugins/ext.rb +0 -2
- data/lib/plugins.rb +0 -2
- data/spec/dummy/config/application.yml +0 -47
- data/spec/routing/accounts_spec.rb +0 -14
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
1
|
class UserGroupsController < ApplicationController
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/app/mailers/notifier.rb
CHANGED
|
@@ -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
|
data/app/models/profile.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
data/app/models/user_group.rb
CHANGED
|
@@ -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
|