Top Level Namespace

Defined Under Namespace

Modules: Hubbard Classes: HubbardException, Project

Constant Summary collapse

DEFAULTS =
{ :format => formats.first }
OPTIONS =
{}
OPTS =
OptionParser.new do |opts|
  opts.banner = <<BANNER
Usage: hubbard [options] <command>

Projects:
list-projects
create-project <project>
delete-project <project>

Repositories:
list-repositories <project>
create-repository <project> <repository>
delete-repository <project> <repository>
fork-repository <from-project> <from-repository> <to-project> <to-repository>
list-forks <project> <repository>

Permissions:
list-permissions <project>
add-permission <project> <username> read|write|admin
remove-permission <project> <username>

Options:
BANNER

  opts.on("--private", "Create project with visibility set to private") do |o|
    OPTIONS[:private] = o
  end
  opts.on("-f", "--format [FORMAT]", formats,
          "Output format (#{formats.join(', ')})") do |o|
    OPTIONS[:format] = o
  end
end
USERNAME =
next_arg "Please specify the username to run as"

Instance Method Summary collapse

Instance Method Details

#authorize(project_name, action) ⇒ Object



118
119
120
121
122
# File 'bin/hubbard', line 118

def authorize(project_name, action)
  unless is_authorized(project_name, action)
    error 3, "You don't have permission to do that"
  end
end

#check_status(msg) ⇒ Object



75
76
77
78
79
# File 'bin/hubbard', line 75

def check_status(msg)
  if $!.exitstatus != 0
    error $!.exitstatus, msg
  end
end

#error(exitstatus, message) ⇒ Object

Raises:



57
58
59
# File 'bin/hubbard', line 57

def error(exitstatus,message)
  raise HubbardException.new(exitstatus), message
end

#find_account_dir(user_name) ⇒ Object



145
146
147
# File 'bin/hubbard', line 145

def (user_name)
  File.join(Hubbard::ACCOUNTS_PATH, user_name)
end

#find_project_dir(project_name) ⇒ Object



149
150
151
# File 'bin/hubbard', line 149

def find_project_dir(project_name)
  File.join(Hubbard::PROJECTS_PATH, project_name)
end

#find_repository_dir(project_name, repository_dir) ⇒ Object



153
154
155
# File 'bin/hubbard', line 153

def find_repository_dir(project_name, repository_dir)
  File.join(find_project_dir(project_name), repository_dir + '.git')
end

#implies(a1, a2) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
# File 'bin/hubbard', line 105

def implies(a1, a2)
  case a1
  when 'admin'
    true
  when 'write'
    a2 != 'admin'
  when 'read'
      a2 == 'read'
  else
    raise "Unknown action type: *#{a1}*"
  end
end

#is_authorized(project_name, action) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'bin/hubbard', line 124

def is_authorized(project_name, action)
  project_dir = find_project_dir(project_name)
  return false unless File.exist?(project_dir)
  return true if @username == 'admin'
  Dir.chdir(project_dir) do
    if action == 'read' && File.read('.visibility').strip == 'public'
      return true
    end
    return false unless File.exist?(".permissions")
    File.read(".permissions").split("\n").each do |line|
      permission = line.strip.split('=')
      line_username = permission[0]
      line_action = permission[1]
      if line_username == @username && implies(line_action, action)
        return true
      end
    end
    false
  end
end

#next_arg(msg) ⇒ Object



61
62
63
64
65
66
# File 'bin/hubbard', line 61

def next_arg(msg)
  if ARGV.length < 1
    error 1, msg
  end
  ARGV.shift
end

#read_project_nameObject



157
158
159
160
161
# File 'bin/hubbard', line 157

def read_project_name
  project_name = next_arg("Please specify a project name")
  validate_project_name(project_name)
  project_name
end

#read_repository_nameObject



163
164
165
166
167
# File 'bin/hubbard', line 163

def read_repository_name
  repository_name = next_arg("Please specify a repository name")
  validate_repository_name(repository_name)
  repository_name
end

#read_user_nameObject



169
170
171
172
173
# File 'bin/hubbard', line 169

def read_user_name
  user_name = next_arg("Please specify a username")
  validate_user_name(user_name)
  user_name
end

#rest_args(msg) ⇒ Object



68
69
70
71
72
73
# File 'bin/hubbard', line 68

def rest_args(msg)
  if ARGV.length < 1
    error 1, msg
  end
  ARGV
end

#run_commandObject



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'bin/hubbard', line 198

def run_command
  OPTS.parse!
  @options = DEFAULTS.merge(OPTIONS)
  @options.freeze

  command = next_arg "Please specify a command to run"

  if command == 'help'
    puts OPTS
    puts
    return 0
  end

  @username = USERNAME

  if command == "run-as"
    if USERNAME != "admin"
      $stderr.puts "You don't have permission to do that"
      return 1
     end 
    @username = next_arg "Please specify the username to run as"
    command = next_arg "Please specify a command to run"
  end

  command_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "commands", "#{command}.rb"))

  if File.exist?(command_file)
    begin
      load command_file
    rescue SystemCallError => e
      $stderr.puts "SystemCallError [#{e.errno}]: #{e.message}"
      return e.errno
    end
  else
    $stderr.puts "Unknown command: #{command}"
    return 1
  end
end

#sync_keysObject



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'bin/hubbard', line 175

def sync_keys
  File.open(File.expand_path("~/.ssh/authorized_keys"), "w") do |file|
    Dir.entries(Hubbard::ACCOUNTS_PATH).each do ||
      next if  == '.' ||  == '..'
      key_dir = File.join(Hubbard::ACCOUNTS_PATH, , "keys")
      Dir.entries(key_dir).each do |name|
        next if name == '.' || name == '..'
        key = File.read(File.join(key_dir, name))
        file << %Q~command="hubbard #{}",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty #{key} #{name}\n~
      end
    end
  end
end

#validate_action_name(action) ⇒ Object



99
100
101
102
103
# File 'bin/hubbard', line 99

def validate_action_name(action)
  unless Hubbard::ACTIONS.member?(action)
    error 1, "Not a valid action (must be one of: read, write, admin)"
  end 
end

#validate_project_name(name) ⇒ Object



81
82
83
84
85
# File 'bin/hubbard', line 81

def validate_project_name(name)
  if name !~ /#{Hubbard::PROJECT_REGEX}/
    error 1, "Project names can only contain letter, numbers, and hyphens"
  end 
end

#validate_repository_name(name) ⇒ Object



87
88
89
90
91
# File 'bin/hubbard', line 87

def validate_repository_name(name)
  if name !~ /#{Hubbard::REPOSITORY_REGEX}/
    error 1, "Repository names can only contain letter, numbers, and hyphens"
  end 
end

#validate_user_name(name) ⇒ Object



93
94
95
96
97
# File 'bin/hubbard', line 93

def validate_user_name(name)
  if name !~ /#{Hubbard::USERNAME_REGEX}/
    error 1, "User names can only contain letter, numbers, and hyphens"
  end 
end