Class: Superhosting::Controller::User
- Inherits:
-
Base
- Object
- Base
- Base
- Superhosting::Controller::User
show all
- Defined in:
- lib/superhosting/controller/user.rb
Constant Summary
collapse
- USER_NAME_FORMAT =
/^[a-zA-Z][-a-zA-Z0-9_]{,31}$/
Instance Attribute Summary
Attributes inherited from Base
#config, #lib
Instance Method Summary
collapse
-
#_add(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}") ⇒ Object
-
#_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil) ⇒ Object
-
#_add_system_user(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}") ⇒ Object
-
#_create_password(generate: false) ⇒ Object
-
#_del(name:) ⇒ Object
-
#_get(name:) ⇒ Object
-
#_group_add(name:) ⇒ Object
-
#_group_del(name:) ⇒ Object
-
#_group_del_users(name:) ⇒ Object
-
#_group_get(name:) ⇒ Object
-
#_group_get_system_users(name:) ⇒ Object
-
#_group_get_users(name:) ⇒ Object
-
#_group_get_users_names(name:) ⇒ Object
-
#_group_pretty_add(name:) ⇒ Object
-
#_group_pretty_del(name:) ⇒ Object
-
#_list(container_name:) ⇒ Object
-
#_pretty_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil) ⇒ Object
-
#_pretty_del(name:, group:) ⇒ Object
-
#_update_password(name:, encrypted_password:) ⇒ Object
-
#add(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false) ⇒ Object
-
#adding_validation(name:, container_name:) ⇒ Object
-
#change(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false) ⇒ Object
-
#delete(name:, container_name:) ⇒ Object
-
#existing_validation(name:, container_name:) ⇒ Object
-
#initialize(**kwargs) ⇒ User
constructor
-
#list(container_name:) ⇒ Object
-
#not_existing_validation(name:, container_name:) ⇒ Object
-
#passwd(name:, container_name:, generate: false) ⇒ Object
Methods inherited from Base
#repair
Methods inherited from Base
#get_base_controller_options, #get_controller
Methods included from Helpers
#instance_variables_to_hash
#_config, #_config_options, #_save_registry!, #apply, #configure, #configure_with_apply, #reconfig, #unapply, #unconfigure, #unconfigure_with_unapply
#_command, #_command_without_debug, #command, #command!
#chmod!, #chown!, #chown_r!, #safe_link!, #safe_unlink!
#__debug, #__dry_run, #__dry_run=, #__logger, #__logger=, #debug, #debug_block, #debug_operation, #indent, #indent=, #indent_reset, #indent_step, #indent_step_back, #info, #storage, #t, #with_dry_run, #with_indent, #with_logger
Constructor Details
#initialize(**kwargs) ⇒ User
Returns a new instance of User.
6
7
8
9
|
# File 'lib/superhosting/controller/user.rb', line 6
def initialize(**kwargs)
super(**kwargs)
@container_controller = self.get_controller(Container)
end
|
Instance Method Details
#_add(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}") ⇒ Object
83
84
85
86
|
# File 'lib/superhosting/controller/user.rb', line 83
def _add(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}")
user = self._get(name: container_name)
self._add_custom(name: "#{container_name}_#{name}", group: container_name, shell: shell, home_dir: home_dir, uid: user.uid)
end
|
#_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil) ⇒ Object
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/superhosting/controller/user.rb', line 92
def _add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil)
if (resp = self.adding_validation(name: name, container_name: group)).net_status_ok?
container_lib_mapper = @lib.containers.f(group)
passwd_mapper = container_lib_mapper.config.f('etc-passwd')
useradd_command = "useradd #{name} -g #{group} -d #{home_dir} -s #{shell}".split
useradd_command += "-u #{uid} -o".split unless uid.nil?
self.command!(useradd_command, debug: false)
user = self._get(name: name)
self.with_dry_run do |dry_run|
user_gid, user_uid = dry_run ? ['XXXX', 'XXXX'] : [user.gid, user.uid]
passwd_mapper.append_line!("#{name}:x:#{user_uid}:#{user_gid}::#{home_dir}:#{shell}")
end
end
resp
end
|
#_add_system_user(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}") ⇒ Object
88
89
90
|
# File 'lib/superhosting/controller/user.rb', line 88
def _add_system_user(name:, container_name:, shell: '/usr/sbin/nologin', home_dir: "/web/#{container_name}")
self._add_custom(name: "#{container_name}_#{name}", group: container_name, shell: shell, home_dir: home_dir)
end
|
#_create_password(generate: false) ⇒ Object
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/superhosting/controller/user.rb', line 141
def _create_password(generate: false)
password = if generate
SecureRandom.hex
else
while 1
if (pass = ask('Enter password: ') { |q| q.echo = false }) != ask('Repeat password: ') { |q| q.echo = false }
self.info('Passwords does not match')
elsif !StrongPassword::StrengthChecker.new(pass).is_strong?(min_entropy: @config.f('password_strength', default: '15').to_i)
self.info('Password is weak')
else
break
end
end
pass
end
encrypted_password = UnixCrypt::SHA512.build(password)
{ password: password, encrypted_password: encrypted_password }
end
|
#_del(name:) ⇒ Object
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/superhosting/controller/user.rb', line 130
def _del(name:)
self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
self.with_dry_run do |dry_run|
resp = {}
resp = self.command!("userdel #{name}", debug: false) unless dry_run
blk.call(code: :deleted)
resp
end
end
end
|
#_get(name:) ⇒ Object
75
76
77
78
79
80
81
|
# File 'lib/superhosting/controller/user.rb', line 75
def _get(name:)
begin
Etc.getpwnam(name)
rescue ArgumentError => e
nil
end
end
|
#_group_add(name:) ⇒ Object
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/superhosting/controller/user.rb', line 179
def _group_add(name:)
self.debug_operation(desc: { code: :group, data: { name: name } }) do |&blk|
self.with_dry_run do |dry_run|
resp = {}
resp = self.command!("groupadd #{name}", debug: false) unless dry_run
blk.call(code: :added)
resp
end
end
end
|
#_group_del(name:) ⇒ Object
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/superhosting/controller/user.rb', line 194
def _group_del(name:)
self.debug_operation(desc: { code: :group, data: { name: name } }) do |&blk|
self.with_dry_run do |dry_run|
resp = {}
resp = self.command!("groupdel #{name}", debug: false) unless dry_run
blk.call(code: :deleted)
resp
end
end
end
|
#_group_del_users(name:) ⇒ Object
235
236
237
|
# File 'lib/superhosting/controller/user.rb', line 235
def _group_del_users(name:)
self._group_get_users_names(name: name).each {|user| self._del(name: user) }
end
|
#_group_get(name:) ⇒ Object
171
172
173
174
175
176
177
|
# File 'lib/superhosting/controller/user.rb', line 171
def _group_get(name:)
begin
Etc.getgrnam(name)
rescue ArgumentError => e
nil
end
end
|
#_group_get_system_users(name:) ⇒ Object
227
228
229
230
231
232
233
|
# File 'lib/superhosting/controller/user.rb', line 227
def _group_get_system_users(name:)
if (base_user = self._get(name: name))
self._group_get_users(name: name).map {|u| u.name.slice(/(?<=#{name}_).*/) if u.uid != base_user.uid }.compact
else
[]
end
end
|
#_group_get_users(name:) ⇒ Object
209
210
211
212
213
214
215
216
217
218
219
220
221
|
# File 'lib/superhosting/controller/user.rb', line 209
def _group_get_users(name:)
if (group = self._group_get(name: name))
gid = group.gid
users = []
Etc.passwd do |user|
users << user if user.gid == gid
end
users
else
[]
end
end
|
#_group_get_users_names(name:) ⇒ Object
223
224
225
|
# File 'lib/superhosting/controller/user.rb', line 223
def _group_get_users_names(name:)
self._group_get_users(name: name).map(&:name)
end
|
#_group_pretty_add(name:) ⇒ Object
190
191
192
|
# File 'lib/superhosting/controller/user.rb', line 190
def _group_pretty_add(name:)
self._group_add(name: name) if self._group_get(name: name).nil?
end
|
#_group_pretty_del(name:) ⇒ Object
205
206
207
|
# File 'lib/superhosting/controller/user.rb', line 205
def _group_pretty_del(name:)
self._group_del(name: name) unless self._group_get(name: name).nil?
end
|
#_list(container_name:) ⇒ Object
19
20
21
|
# File 'lib/superhosting/controller/user.rb', line 19
def _list(container_name:)
self._group_get_users_names(name: container_name)
end
|
#_pretty_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/superhosting/controller/user.rb', line 111
def _pretty_add_custom(name:, group:, shell: '/usr/sbin/nologin', home_dir: "/web/#{group}", uid: nil)
self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
if self._get(name: name)
blk.call(code: :ok)
{}
else
self._add_custom(name: name, group: group, shell: shell, home_dir: home_dir, uid: uid).tap do
blk.call(code: :added)
end
end
end
end
|
#_pretty_del(name:, group:) ⇒ Object
124
125
126
127
128
|
# File 'lib/superhosting/controller/user.rb', line 124
def _pretty_del(name:, group:)
with_adding_group = self._group_get_users(name: group).one? ? true : false
self._del(name: name)
self._group_add(name: group) if with_adding_group
end
|
#_update_password(name:, encrypted_password:) ⇒ Object
160
161
162
163
164
165
166
167
168
169
|
# File 'lib/superhosting/controller/user.rb', line 160
def _update_password(name:, encrypted_password:)
self.debug_operation(desc: { code: :user, data: { name: name } }) do |&blk|
self.with_dry_run do |dry_run|
resp = {}
resp = self.command!("usermod -p '#{encrypted_password}' #{name}", debug: false) unless dry_run
blk.call(code: :updated)
resp
end
end
end
|
#add(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# File 'lib/superhosting/controller/user.rb', line 23
def add(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false)
return { error: :logical_error, code: :option_ftp_only_is_required } if ftp_dir and !ftp_only
web_mapper = PathMapper.new("/web/#{container_name}")
home_dir = ftp_dir.nil? ? web_mapper.path : web_mapper.f(ftp_dir).path
if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
if !File.exists? home_dir
resp = { error: :logical_error, code: :incorrect_ftp_dir, data: { dir: home_dir.to_s } }
elsif (resp = self.not_existing_validation(name: name, container_name: container_name)).net_status_ok?
shell = ftp_only ? '/usr/sbin/nologin' : '/bin/bash'
if (resp = self._add(name: name, container_name: container_name, home_dir: home_dir, shell: shell)).net_status_ok?
if generate
resp = self.passwd(name: name, container_name: container_name, generate: generate)
end
end
end
end
resp
end
|
#adding_validation(name:, container_name:) ⇒ Object
239
240
241
242
|
# File 'lib/superhosting/controller/user.rb', line 239
def adding_validation(name:, container_name:)
return { error: :input_error, code: :invalid_user_name, data: { name: name, regex: USER_NAME_FORMAT } } if name !~ USER_NAME_FORMAT
self.not_existing_validation(name: name, container_name: container_name)
end
|
#change(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false) ⇒ Object
67
68
69
70
71
72
73
|
# File 'lib/superhosting/controller/user.rb', line 67
def change(name:, container_name:, ftp_dir: nil, ftp_only: false, generate: false)
if (resp = self.delete(name: name, container_name: container_name)).net_status_ok?
self.add(name: name, container_name: container_name, ftp_dir: ftp_dir, ftp_only: ftp_only, generate: generate)
else
resp
end
end
|
#delete(name:, container_name:) ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
|
# File 'lib/superhosting/controller/user.rb', line 55
def delete(name:, container_name:)
if (resp = @container_controller.available_validation(name: container_name)).net_status_ok? and
(resp = self.existing_validation(name: name, container_name: container_name)).net_status_ok?
container_lib_mapper = @lib.containers.f(container_name)
passwd_mapper = container_lib_mapper.config.f('etc-passwd')
user_name = "#{container_name}_#{name}"
self._del(name: user_name)
passwd_mapper.remove_line!(/^#{user_name}:.*/)
end
resp
end
|
#existing_validation(name:, container_name:) ⇒ Object
244
245
246
247
|
# File 'lib/superhosting/controller/user.rb', line 244
def existing_validation(name:, container_name:)
user_name = "#{container_name}_#{name}"
PathMapper.new('/etc/passwd').check(user_name) ? {} : { error: :logical_error, code: :user_does_not_exists, data: { name: user_name } }
end
|
#list(container_name:) ⇒ Object
11
12
13
14
15
16
17
|
# File 'lib/superhosting/controller/user.rb', line 11
def list(container_name:)
if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
{ data: self._list(container_name: container_name) }
else
resp
end
end
|
#not_existing_validation(name:, container_name:) ⇒ Object
249
250
251
|
# File 'lib/superhosting/controller/user.rb', line 249
def not_existing_validation(name:, container_name:)
self.existing_validation(name: name, container_name: container_name).net_status_ok? ? { error: :logical_error, code: :user_exists, data: { name: "#{container_name}_#{name}" } } : {}
end
|
#passwd(name:, container_name:, generate: false) ⇒ Object
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/superhosting/controller/user.rb', line 44
def passwd(name:, container_name:, generate: false)
if (resp = @container_controller.available_validation(name: container_name)).net_status_ok?
user_name = "#{container_name}_#{name}"
passwords = self._create_password(generate: generate)
self._update_password(name: user_name, encrypted_password: passwords[:encrypted_password])
generate ? { data: passwords[:password] } : {}
else
resp
end
end
|