Class: Pawnee::Actions::User

Inherits:
BaseModel show all
Defined in:
lib/pawnee/pawnee/actions/user.rb

Overview

The user class handles creating, updating, and deleting users. Users are tied to the login attribute and all other attributes will update based on that login.

Passwords

Instead of putting passwords in code, you should either:

1) not use a password (which is fine for system users) or 2) Set the password value to an encryped password. You can generated an encryped password with the following ruby command:

ruby -e "puts 'password'.crypt('passphrase')"

Instance Attribute Summary collapse

Attributes inherited from BaseModel

#new_record

Instance Method Summary collapse

Methods inherited from BaseModel

change_attr_accessor, #new_record?, #update_attributes

Constructor Details

#initialize(base, attributes) ⇒ User

Returns a new instance of User.



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/pawnee/pawnee/actions/user.rb', line 48

def initialize(base, attributes)
  @base = base
  
  if attributes[:login]
    self. = attributes[:login]
    # Read the current attributes from the system
    read_from_system()
  end
  
  # Set the attributes, track what changed
  update_attributes(attributes)
end

Instance Attribute Details

#baseObject

Returns the value of attribute base.



46
47
48
# File 'lib/pawnee/pawnee/actions/user.rb', line 46

def base
  @base
end

Instance Method Details

#destroyObject



168
169
170
171
172
173
# File 'lib/pawnee/pawnee/actions/user.rb', line 168

def destroy
  self.new_record = true
  base.as_root do
    base.exec("userdel #{}", :no_pty => true)
  end
end

#exec(*args) ⇒ Object



61
62
63
# File 'lib/pawnee/pawnee/actions/user.rb', line 61

def exec(*args)
  return base.exec(*args)
end

#home_for_user(find_user) ⇒ Object



85
86
87
88
# File 'lib/pawnee/pawnee/actions/user.rb', line 85

def home_for_user(find_user)
  home, shell = passwd_data(find_user)
  return home
end

#passwd_data(find_user) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/pawnee/pawnee/actions/user.rb', line 69

def passwd_data(find_user)
  passwd_data = base.destination_files.binread('/etc/passwd')

  if passwd_data
    passwd_data.split(/\n/).each do |line|
      user, *_, home, shell = line.split(':')
    
      if user == find_user
        return home, shell
      end
    end
  end
  
  return nil, nil        
end

#read_from_systemObject

Pull in the current (starting) state of the attributes for the User model



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/pawnee/pawnee/actions/user.rb', line 97

def read_from_system
  @uid, stderr, exit_code, _ = exec("id -u #{}", :with_codes => true, :log_stderr => false, :no_pty => true)
  @uid = @uid.strip
  if exit_code == 0
    # The login exists, load in more data
    @gid = exec("id -g #{}", :log_stderr => false, :no_pty => true).strip
    
    @groups = exec("groups #{}", :no_pty => true).gsub(/^[^:]+[:]/, '').strip.split(/ /).sort
    @home = home_for_user()
    
    # TODO: Load in existing shell
    @shell = shell_for_user()
    self.new_record = false

    # Reject any ones we just changed, so its as if we did a find with these
    @changed_attributes = @changed_attributes.reject {|k,v| [:uid, :gid, :groups, :login].include?(k.to_sym) }
    @original_groups_value = @groups.dup
  else
    # No user
    @uid = nil
    @groups ||= []
    @shell ||= '/bin/bash'
    self.shell_will_change!
    self.new_record = true
  end
end

#run(*args) ⇒ Object



65
66
67
# File 'lib/pawnee/pawnee/actions/user.rb', line 65

def run(*args)
  return base.run(*args)
end

#saveObject

Write any changes out



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/pawnee/pawnee/actions/user.rb', line 125

def save
  # Since groups is an array, we have to manually check to see if
  # its changed, because people can do << to it
  if @original_groups_value != @groups
    # Mark as changed
    self.groups_will_change!
    
    @original_groups_value = @groups
  end
  
  if changed?
    raise "A login must be specified" unless 
    
    if new_record?
      # Just create a new user
      command = ["useradd"]
      base.say_status :create_user, , :green
    else
      # Modify an existing user
      command = ["usermod"]
      base.say_status :update_user, , :green
    end
    
    # Set options
    command << "-u #{uid}" if uid && uid_changed?
    command << "-g #{gid}" if gid && gid_changed?
    command << "-G #{groups.join(',')}" if groups && groups_changed? && groups.size != 0
    command << "-c #{comment.inspect}" if comment && comment_changed?
    command << "-s #{shell.inspect}" if shell && shell_changed?
    command << "-p #{password.inspect}" if password && password_changed?
    
    # TODO: If update, we need to make the directory first to move things to
    command << "-m -d #{home.inspect}" if home && home_changed?
    command << 
    
    base.as_root do
      base.exec(command.join(' '), :no_pty => true)
    end
  else
    base.say_status :user_exists, , :blue
  end
end

#shell_for_user(find_user) ⇒ Object



90
91
92
93
# File 'lib/pawnee/pawnee/actions/user.rb', line 90

def shell_for_user(find_user)
  home, shell = passwd_data(find_user)
  return shell
end