• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-users / 10734406603

06 Sep 2024 07:36AM UTC coverage: 60.799%. Remained the same
10734406603

push

github

lslezak
Adapt files for the SLE-15-SP7 branch

3395 of 5584 relevant lines covered (60.8%)

35.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.03
/src/lib/y2users/users_module/reader.rb
1
# Copyright (c) [2021] SUSE LLC
2
#
3
# All Rights Reserved.
4
#
5
# This program is free software; you can redistribute it and/or modify it
6
# under the terms of version 2 of the GNU General Public License as published
7
# by the Free Software Foundation.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12
# more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with this program; if not, contact SUSE LLC.
16
#
17
# To contact SUSE LLC about this file by physical or electronic mail, you may
18
# find current contact information at www.suse.com.
19

20
require "yast"
1✔
21
require "y2users/config"
1✔
22
require "y2users/user"
1✔
23
require "y2users/home"
1✔
24
require "y2users/group"
1✔
25
require "y2users/password"
1✔
26
require "y2users/login_config"
1✔
27
require "y2users/useradd_config"
1✔
28

29
Yast.import "Users"
1✔
30
Yast.import "Autologin"
1✔
31

32
module Y2Users
1✔
33
  module UsersModule
1✔
34
    # Class for reading the configuration from Yast::Users module
35
    class Reader
1✔
36
      # Generates two new configs with the information from YaST::Users module
37
      #
38
      # @return [Array<Config>] returns pair of configs. system one and modified one
39
      def read
1✔
40
        system_config = Config.new
1✔
41
        target_config = Config.new
1✔
42
        read_elements(system_config, target_config)
1✔
43
        read_autologin(target_config)
1✔
44
        read_useradd_defaults(target_config)
1✔
45

46
        [system_config, target_config]
1✔
47
      end
48

49
    private
1✔
50

51
      # Reads the useradd defaults from Users module
52
      #
53
      # @param config [Config]
54
      # @return [UseraddConfig]
55
      def read_useradd_defaults(config)
1✔
56
        users_map = Yast::Users.GetLoginDefaults
1✔
57
        # notes: groups are deprecated and usrskel and create_mail_spool is not in users
58
        y2users_map = {
1✔
59
          group:             users_map["group"],
60
          home:              users_map["home"],
61
          umask:             users_map["umask"],
62
          expiration:        users_map["expire"],
63
          inactivity_period: users_map["inactive"]&.to_i,
64
          shell:             users_map["shell"],
65
          skel:              users_map["skel"]
66
        }
67

68
        config.useradd = UseraddConfig.new(y2users_map)
1✔
69
      end
70

71
      # Reads the Autologin config from Autologin module
72
      #
73
      # @note Users reads and sets autologin directly and does not expose it
74
      #   so it is easier to read it directly
75
      #
76
      # @param config [Config]
77
      # @return [LoginConfig]
78
      def read_autologin(config)
1✔
79
        res = LoginConfig.new
1✔
80
        res.autologin_user = if Yast::Autologin.user.empty?
1✔
81
          nil
×
82
        else
83
          config.users.by_name(Yast::Autologin.user)
1✔
84
        end
85
        res.passwordless = Yast::Autologin.pw_less
1✔
86

87
        config.login = res
1✔
88
      end
89

90
      # Reads the users and groups
91
      #
92
      # @param system_config [Config]
93
      # @param target_config [Config]
94
      def read_elements(system_config, target_config)
1✔
95
        read_groups(system_config, target_config)
1✔
96
        read_users(system_config, target_config)
1✔
97
      end
98

99
      # Returns the list of users
100
      #
101
      # @param system_config [Config]
102
      # @param target_config [Config]
103
      def read_users(system_config, target_config)
1✔
104
        all_local = Yast::Users.GetUsers("uid", "local").values +
1✔
105
          Yast::Users.GetUsers("uid", "system").values
106
        all_local.each do |user_hash|
1✔
107
          if user_hash["modified"] == "added" # new user
2✔
108
            target_config.attach(user(user_hash, target_config))
1✔
109
          else # everything else is edit of different kinds
110
            # at first create original user
111
            system_user = user(user_hash.merge(user_hash["org_user"] || {}), system_config)
1✔
112
            system_config.attach(system_user)
1✔
113
            target_user = user(user_hash, target_config)
1✔
114
            target_user.assign_internal_id(system_user.id)
1✔
115
            target_config.attach(target_user)
1✔
116
          end
117
        end
118
        removed_users = Yast::Users.RemovedUsers
1✔
119
        ["local", "system"].each do |type|
1✔
120
          next unless removed_users[type]
2✔
121

122
          removed_users[type].values.each { |u| system_config.attach(user(u, system_config)) }
3✔
123
        end
124
      end
125

126
      def read_groups(system_config, target_config)
1✔
127
        all_local = Yast::Users.GetGroups("cn", "local").values +
1✔
128
          Yast::Users.GetGroups("cn", "system").values
129
        all_local.each do |group_hash|
1✔
130
          if group_hash["modified"] == "added" # new group
4✔
131
            target_config.attach(group(group_hash))
1✔
132
          else # everything else is edit of different kinds
133
            # at first create original group
134
            system_group = group(group_hash.merge(group_hash["org_group"] || {}))
3✔
135
            system_config.attach(system_group)
3✔
136
            target_group = group(group_hash)
3✔
137
            target_group.assign_internal_id(system_group.id)
3✔
138
            target_config.attach(target_group)
3✔
139
          end
140
        end
141
        removed_groups = Yast::Users.RemovedGroups
1✔
142
        ["local", "system"].each do |type|
1✔
143
          next unless removed_groups[type]
2✔
144

145
          removed_groups[type].values.each { |u| system_config.attach(group(u)) }
2✔
146
        end
147
      end
148

149
      # Creates a {User} object based on the data structure of a Users user
150
      #
151
      # @param user_attrs [Hash] a user representation in the format used by Users
152
      # @param config [Config]
153
      # @return [User]
154
      def user(user_attrs, config)
1✔
155
        User.new(user_attrs["uid"]).tap do |user|
5✔
156
          user.uid = attr_value(:uidNumber, user_attrs)&.to_s
5✔
157
          user.gid = user_gid(user_attrs, config)
5✔
158
          user.home = home(user_attrs)
5✔
159
          user.shell = attr_value(:loginShell, user_attrs)
5✔
160
          user.gecos = [
5✔
161
            attr_value(:cn, user_attrs),
162
            *(user_attrs["addit_data"] || "").split(",")
5✔
163
          ].compact
164
          user.system = true if !user.uid && user_attrs["type"] == "system"
5✔
165
          user.receive_system_mail = Yast::Users.GetRootAliases[user.name] == 1
5✔
166

167
          # set password only if specified, nil means not touch it
168
          user.password = create_password(user_attrs) if user_attrs["userPassword"]
5✔
169

170
          # set authorized keys only if set in users module
171
          user.authorized_keys = user_attrs["authorized_keys"] if user_attrs["authorized_keys"]
5✔
172
        end
173
      end
174

175
      # Obtains the gid for the user
176
      #
177
      # @param user_attrs [Hash] a user representation in the format used by Users
178
      # @param config [Config]
179
      #
180
      # @return [String, nil] nil if the gid is unknown
181
      def user_gid(user_attrs, config)
1✔
182
        gid = attr_value(:gidNumber, user_attrs)&.to_s
5✔
183

184
        gid || config.groups.by_name(attr_value["groupname"])&.gid
5✔
185
      end
186

187
      # Creates a home from the given attributes
188
      #
189
      # @param user_attrs [Hash] a user representation in the format used by Users
190
      # @return [Home]
191
      def home(user_attrs)
1✔
192
        Home.new(attr_value(:homeDirectory, user_attrs)).tap do |home|
5✔
193
          # permissions is an octal number starting by 0 (e.g., "0755")
194
          home.permissions = attr_value(:home_mode, user_attrs)&.prepend("0")
5✔
195
          home.btrfs_subvol = attr_value(:btrfs_subvolume, user_attrs)
5✔
196
        end
197
      end
198

199
      # Creates a {Group} object based on the data structure of a Users group
200
      #
201
      # @param group_attrs [Hash] a group representation in the format used by Users
202
      # @return [Group]
203
      def group(group_attrs)
1✔
204
        group = Group.new(group_attrs["cn"])
8✔
205

206
        group.gid = attr_value(:gidNumber, group_attrs)&.to_s
8✔
207
        group.users_name = group_attrs["userlist"].keys
8✔
208
        group.system = true if !group.gid && group_attrs["type"] == "system"
8✔
209

210
        group
8✔
211
      end
212

213
      # Value of the given field for the given Users user
214
      #
215
      # @param attr [#to_s] name of the attribute
216
      # @param user [Hash] a user or group representation in the format used by Users
217
      # @return [String, nil] nil if the value is missing or empty
218
      def attr_value(attr, user)
1✔
219
        value = user[attr.to_s]
43✔
220
        return nil if value == ""
43✔
221

222
        value
41✔
223
      end
224

225
      # Creates a {Password} object based on the data structure of a Users user
226
      #
227
      # @param user [Hash] a user representation in the format used by Users
228
      # @return [Password]
229
      def create_password(user)
1✔
230
        create_method = user["encrypted"] ? :create_encrypted : :create_plain
5✔
231

232
        Password.public_send(create_method, user["userPassword"]).tap do |password|
5✔
233
          last_change = user["shadowLastChange"]
5✔
234
          expiration = user["shadowExpire"]
5✔
235

236
          password.aging = PasswordAging.new(last_change) if last_change
5✔
237
          password.minimum_age = user["shadowMin"]&.to_s
5✔
238
          password.maximum_age = user["shadowMax"]&.to_s
5✔
239
          password.warning_period = user["shadowWarning"]&.to_s
5✔
240
          password.inactivity_period = user["shadowInactive"]&.to_s
5✔
241
          password.account_expiration = AccountExpiration.new(expiration) if expiration
5✔
242
        end
243
      end
244
    end
245
  end
246
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc