Class: Keyman::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/keyman/server.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeServer

Returns a new instance of Server.



6
7
8
# File 'lib/keyman/server.rb', line 6

def initialize
  @users = {}
end

Instance Attribute Details

#groupObject

Returns the value of attribute group.



4
5
6
# File 'lib/keyman/server.rb', line 4

def group
  @group
end

#host(host = nil) ⇒ Object

Returns or sets the hostname of the server which should be used when connecting and identifying this server



31
32
33
# File 'lib/keyman/server.rb', line 31

def host
  @host
end

#location(location = nil) ⇒ Object

Returns or sets the location of the server



43
44
45
# File 'lib/keyman/server.rb', line 43

def location
  @location
end

#usersObject

Returns the value of attribute users.



4
5
6
# File 'lib/keyman/server.rb', line 4

def users
  @users
end

Class Method Details

.add(&block) ⇒ Object

Adds a new server by accepting a block of objects



11
12
13
14
15
16
# File 'lib/keyman/server.rb', line 11

def self.add(&block)
  s = self.new
  s.instance_eval(&block)
  Keyman.servers << s
  s
end

.add_by_name(host, options = {}) ⇒ Object

Adds a new server based on it’s name and location



19
20
21
22
23
24
25
26
27
# File 'lib/keyman/server.rb', line 19

def self.add_by_name(host, options = {})
  s = self.new
  s.host = host
  s.location = options[:location]
  s.users = options[:users]
  s.group = options[:group]
  Keyman.servers << s
  s
end

Instance Method Details

#authorized_keys(username) ⇒ Object

Returns a full string output for the authorized_keys file. Passes the user who’s file you wish to generate.



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/keyman/server.rb', line 61

def authorized_keys(username)
  Array.new.tap do |a|
    a << "# SSH Authorized Keys file generated automatically by Keyman"
    a << "# Generated at: #{Time.now.utc} for #{@host}"
    a << nil
    authorized_users(username).each do |u|
      a << "# #{u.name}"
      a << u.key + "\n"
    end
  end.join("\n")
end

#authorized_users(username) ⇒ Object

Returns an array of users who have access to this server. Includes all objects from within the server



49
50
51
52
53
54
55
56
57
# File 'lib/keyman/server.rb', line 49

def authorized_users(username)
  @users[username].map do |k|
    if obj = Keyman.user_or_group_for(k)
      obj.is_a?(Group) ? obj.users : obj
    else
      nil
    end
  end.flatten.compact.uniq
end

#push!Object

Push the authorized keys file to the appropriate server for the users configured here. This will not succeed if the current user does not already have a key on the server.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/keyman/server.rb', line 76

def push!
  passwords_to_try = (Keyman.password_cache ||= [nil]).dup
  @users.each do |user, objects|
    begin
      passwords_to_try.each do |password|
        Timeout.timeout(10) do |t|
          Net::SSH.start(self.host, user, :password => password) do |ssh|
            ssh.exec!("mkdir -p ~/.ssh")
            file = authorized_keys(user).gsub("\n", "\\n").gsub("\t", "\\t")
            ssh.exec!("echo -e '#{file}' > ~/.ssh/authorized_keys")
          end
          Keyman.password_cache << password if password
        end
      end
      puts "\e[32mPushed authorized_keys to #{user}@#{self.host}\e[0m"
    rescue Net::SSH::AuthenticationFailed
      passwords_to_try.shift
      if passwords_to_try.empty?
        puts "\e[35mAuthorization failed on to #{user}@#{self.host}.\e[0m"
        password = HighLine.ask("Enter password: ") { |q| q.echo = "*" }
        if password.length > 0
          passwords_to_try << password
          retry
        else
          puts "\e[37mSkipping #{user}@#{self.host}\e[0m"
        end
      else
        retry
      end
    rescue Timeout::Error
      puts "\e[31mTimed out while uploading authorized_keys to #{user}@#{self.host}\e[0m"
    rescue => e
      puts "\e[31mFailed to upload authorized_keys to #{user}@#{self.host} (#{e.class})\e[0m"
      puts e.message
    end
  end
end

#user(name, *access_objects) ⇒ Object

Sets a user on the server along with the access objects which should be granted access



37
38
39
40
# File 'lib/keyman/server.rb', line 37

def user(name, *access_objects)
  access_objects.each { |ao| raise Error, "!! Invalid access object '#{ao}' on '#{self.host}'" unless Keyman.user_or_group_for(ao) }
  @users[name] = access_objects
end