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, GitCommand::GIT_REPO

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from GitCommand

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

Constructor Details

#initialize(config = nil) ⇒ Session

Initialize a new Session

Parameters:

  • config (Configuration) (defaults to: nil)

    an existing configuration instance



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

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

  if config.raise_errors == true
    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
  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

Parameters:

  • args (Array)

    session arguments

  • env (Hash)

    hash with environment variables, use ENV.to_hash.dup

  • run_git (Boolean) (defaults to: true)

    execute git command if set to true

Raises:



36
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
79
80
81
# File 'lib/git_handler/session.rb', line 36

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]
  )

  if config.log == true
    log_request(request) 
  end

  if config.raise_errors == true
    unless File.exist?(request.repo_path)
      raise SessionError, "Repository #{request.repo} does not exist!"
    end
  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 with catch-all-exceptions wrapper terminates session on SessionError or Exception

Parameters:

  • args (Array)

    session arguments

  • env (Hash)

    hash with environment variables, use ENV.to_hash.dup

  • run_git (Boolean) (defaults to: true)

    execute git command if set to true



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/git_handler/session.rb', line 89

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

Parameters:

  • reason (String) (defaults to: '')
  • exit_status (Fixnum) (defaults to: 1)


105
106
107
108
109
# File 'lib/git_handler/session.rb', line 105

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)


113
114
115
# File 'lib/git_handler/session.rb', line 113

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

#valid_request?Boolean

Check if session request is valid

Returns:

  • (Boolean)


119
120
121
122
123
124
125
126
# File 'lib/git_handler/session.rb', line 119

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