Class: GitHandler::Session

Inherits:
Object
  • Object
show all
Includes:
GitCommand
Defined in:
lib/git_handler/session.rb

Constant Summary

Constants included from GitCommand

GitCommand::COMMANDS_READONLY, GitCommand::COMMANDS_WRITE, GitCommand::GIT_COMMAND

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from GitCommand

#parse_command, #read_command?, #valid_command?, #write_command?

Constructor Details

#initialize(config = nil) ⇒ Session

Initialize a new Session

config - GitHandler::Configuration instance



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/git_handler/session.rb', line 14

def initialize(config=nil)
  unless config.kind_of?(GitHandler::Configuration)
    raise SessionError, 'Configuration required!'
  end

  unless File.exists?(config.home_path)
    raise ConfigurationError, "Home path does not exist!"
  end

  unless File.exists?(config.repos_path)
    raise ConfigurationError, "Repositories path does not exist!"
  end

  @config = config
  @log = Logger.new(@config.log_path)
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



7
8
9
# File 'lib/git_handler/session.rb', line 7

def args
  @args
end

#configObject (readonly)

Returns the value of attribute config.



7
8
9
# File 'lib/git_handler/session.rb', line 7

def config
  @config
end

#envObject (readonly)

Returns the value of attribute env.



7
8
9
# File 'lib/git_handler/session.rb', line 7

def env
  @env
end

#logObject (readonly)

Returns the value of attribute log.



8
9
10
# File 'lib/git_handler/session.rb', line 8

def log
  @log
end

Instance Method Details

#execute(args, env, run_git = true) ⇒ Object

Execute session

args - Command arguments env - Environment parameters run_git - Execute git shell if no block provided#

Raises:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/git_handler/session.rb', line 37

def execute(args, env, run_git=true)
  @args = args
  @env  = env

  raise SessionError, "Invalid environment" unless valid_environment?
  raise SessionError, "Invalid git request" unless valid_request?

  command   = parse_command(env['SSH_ORIGINAL_COMMAND'])
  repo_path = File.join(config.repos_path, command[:repo])
  request   = GitHandler::Request.new(
    :remote_ip => env['SSH_CLIENT'].split(' ').first,
    :args      => args,
    :env       => env,
    :repo      => command[:repo],
    :repo_path => repo_path,
    :command   => [command[:action], "'#{repo_path}'"].join(' '),
    :read      => command[:read],
    :write     => command[:write]
  )

  log_request(request)

  unless File.exist?(request.repo_path)
    raise SessionError, "Repository #{request.repo} does not exist!"
  end

  if block_given?
    # Pass all request information for custom processing
    # if no block is defined it will execute git-shell
    # with parameters provided
    yield request
  else
    if run_git == true
      exec("git-shell", "-c", request.command)
    end
  end

  # Interesting part, inspired by github write-up
  # if we need to pass this to another server
  # the process should replace itself with another ssh call:
  # exec("ssh", "git@TARGET", "#{args.join(' ')}")
end

#execute_safe(args, env, run_git = true) ⇒ Object

Execute session in safe manner, catch all exceptions and terminate session



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/git_handler/session.rb', line 83

def execute_safe(args, env, run_git=true)
  begin
    execute(args, env, run_git)
  rescue GitHandler::SessionError => err
    # TODO: Some additional logging here
    terminate(err.message)
  rescue Exception => err
    # TODO: Needs some love here
    terminate(err.message)
  end
end

#terminate(reason = '', exit_status = 1) ⇒ Object

Terminate session execution

reason - Process termination reason message exit_status - Exit code (default: 1)



100
101
102
103
104
# File 'lib/git_handler/session.rb', line 100

def terminate(reason='', exit_status=1)
  logger.error("Session terminated. Reason: #{reason}")
  $stderr.puts("Request failed: #{reason}")
  exit(exit_status)
end

#valid_environment?Boolean

Check if session environment is valid

Returns:

  • (Boolean)


108
109
110
# File 'lib/git_handler/session.rb', line 108

def valid_environment?
  env['USER'] == config.user && env['HOME'] == config.home_path
end

#valid_request?Boolean

Check if session request is valid

Returns:

  • (Boolean)


114
115
116
117
118
119
120
121
# File 'lib/git_handler/session.rb', line 114

def valid_request?
  if env.keys_all?(['SSH_CLIENT', 'SSH_CONNECTION', 'SSH_ORIGINAL_COMMAND'])
    if valid_command?(env['SSH_ORIGINAL_COMMAND'])
      return true
    end
  end
  false
end