Git create remote repository on push

前端 未结 4 482
执念已碎
执念已碎 2020-12-28 15:28

I have been trying to figure this one out but I am having a hard time doing so. I am currently working on an open source project that requires me to allow a user to

4条回答
  •  自闭症患者
    2020-12-28 16:00

    You can write a wrapper script on the remote, and prepend command="/path/to/wrapper" to the authorized_keys' lines.

    command="/usr/local/bin/gitaccess" ssh-rsa ...
    

    In this wrapper you would check SSH_ORIGINAL_COMMAND. Git issues these commands:

    git receive-pack '/path/provided' # when pushing
    git upload-pack '/path/provided' # when pulling
    

    If SSH_ORIGINAL_COMMAND is not empty and starts with one of these, you check the path, create the repository if necessary, install any configuration you need in it, and execute the command.

    If SSH_ORIGINAL_COMMAND is empty and you want to provide users with shell access, you invoke a shell.

    If SSH_ORIGINAL_COMMAND is not empty but doesn't start with a git command, if you want to allow users to have shell access, you just execute the command provided.

    Here's a bit of Ruby code to demonstrate. Note that I didn't test it and there's room for improvement (for example we should not hardcode /bin/bash).

    #!/usr/bin/env ruby
    orig_command = ENV['SSH_ORIGINAL_COMMAND']
    if orig_command.nil?
        # If you want to preserve shell access
        exec '/bin/bash' # not tested, I hope it's interactive if executed this way
    end
    
    cmd_parts = orig_command.match /([a-z-]+) '([a-z0-9.\/]+)'/
    if cmd_parts.nil?
        # If you want to preserve shell access
        exec '/bin/bash', '-c', orig_command
    end
    
    command = cmd_parts[1]
    path = '/var/repositories/'+cmd_parts[2] # not secured (could contain '..')
    
    if command == 'git-receive-pack' || command == 'git-upload-pack'
        if not File.directory?(path)
            `git init --bare #{path}` # not secured, I didn't escape path
            # Do any configuration here
        end
        exec 'git-shell', '-c', "#{command} '#{path}'"
    end
    
    # If you want to preserve shell access
    exec '/bin/bash', '-c', orig_command
    

    You can also pass an argument to this script in the authorized_keys to identify users and choose whether they should have shell access. I also do this to control access on a per-repository basis. If you want to carry this argument to the git hooks, just create an environment variable.

提交回复
热议问题