Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
goerz committed Jan 30, 2016
2 parents f3f8f3c + 65fe621 commit 8a5217c
Show file tree
Hide file tree
Showing 8 changed files with 684 additions and 0 deletions.
60 changes: 60 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
.venv/

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
sudo: false # use container-based infrastructure (pre-requisite for caching)
install:
- pip install -e .[dev]
script:
py.test --cov=tmuxpair.py --doctest-modules tmuxpair.py test_tmuxpair.py
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2016 Michael Goerz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
72 changes: 72 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
PROJECT_NAME = tmuxpair
PACKAGES = pip pytest coverage
TESTPYPI = https://testpypi.python.org/pypi

TESTOPTIONS = -v -s -x --doctest-modules --cov=tmuxpair.py
TESTS = tmuxpair.py test_tmuxpair.py


install:
pip install .

develop:
pip install -e .[dev]

uninstall:
pip uninstall $(PROJECT_NAME)

upload:
python setup.py register
python setup.py sdist upload

test-upload:
python setup.py register -r $(TESTPYPI)
python setup.py sdist upload -r $(TESTPYPI)

test-install:
pip install -i $(TESTPYPI) $(PROJECT_NAME)

.venv/py27/bin/py.test:
@conda create -y -m -p .venv/py27 python=2.7 $(PACKAGES)
@.venv/py27/bin/pip install -e .[dev]

.venv/py33/bin/py.test:
@conda create -y -m -p .venv/py33 python=3.3 $(PACKAGES)
@.venv/py33/bin/pip install -e .[dev]

.venv/py34/bin/py.test:
@conda create -y -m -p .venv/py34 python=3.4 $(PACKAGES)
@.venv/py34/bin/pip install -e .[dev]

.venv/py35/bin/py.test:
@conda create -y -m -p .venv/py35 python=3.5 $(PACKAGES)
@.venv/py35/bin/pip install -e .[dev]

test27: .venv/py27/bin/py.test
$< -v $(TESTOPTIONS) $(TESTS)

test33: .venv/py33/bin/py.test
$< -v $(TESTOPTIONS) $(TESTS)

test34: .venv/py34/bin/py.test
$< -v $(TESTOPTIONS) $(TESTS)

test35: .venv/py35/bin/py.test
$< -v $(TESTOPTIONS) $(TESTS)

test: test27 test33 test34 test35

coverage: test35
@rm -rf htmlcov/index.html
.venv/py35/bin/coverage html

clean:
@rm -f *.pyc
@rm -rf __pycache__
@rm -rf *.egg-info
@rm -rf htmlcov

distclean: clean
@rm -rf .venv

.PHONY: install develop uninstall upload test-upload test-install test clean distclean coverage
72 changes: 72 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# tmuxpair #

[![Build Status](https://travis-ci.org/goerz/tmuxpair.svg)](https://travis-ci.org/goerz/tmuxpair)

Command line script for setting up a temporary tmux session for pair
programming.

© 2016 by [Michael Goerz](http://michaelgoerz.net). This software is available
under the terms of the [MIT license][LICENSE].

[LICENSE]: LICENSE

## Installation & Usage ##

Using [virtualenv][]/[pipsi][]/[conda env][] is recommended. Install the
`tmuxpair` executable with

pip install tmuxpair

[virtualenv]: http://docs.python-guide.org/en/latest/dev/virtualenvs/
[pipsi]: https://github.com/mitsuhiko/pipsi#pipsi
[conda env]: http://conda.pydata.org/docs/using/envs.html

Run `tmuxpair -h` for usage details.

## Reasonably Secure Pair Programming ##

[A simple yet powerful way][1] for pair programming is to have a partner connect
to a tmux session on your machine. However, this implies that you give them SSH
access, with the obvious security implications: Your partner now
has complete control over your user account. They could use `scp` to copy any of
your files, read your email, or [pull a prank on you][2] by messing with your
`.bashrc`.

While you should probably only engage in pair programming with people that you
place a certain minimum amount of trust in, it would be nice to eliminate at
least the obvious ways for your partner to do anything behind your back.
`tmuxpair` achieves this by using [key-based authentication][3] together with the
feature of SSH to [limit a key to a specific command][4]. This follows the
approach outlined in [Tres Trantham’s blog post][5]. Note that we also lock down
`scp` access and port forwarding (which could allow your partner to access any
firewalled server on your network).

We can go a little further in ensuring only supervised access by strictly
limiting your partner’s connection to the duration of the pair-programming
session.`tmuxpair` does this by by wrapping `tmux`; when you run e.g.

tmuxpair partner_key.pub

the public key in the file `partner_key.pub` is *temporarily* appended to your
`~/.ssh/authorized_keys` file (with the appropriate options), and `tmuxpair`
attaches to a tmux session “pair”. As soon as the session ends – or you detach
from it! – your partner’s SSH connection is closed and the original
`authorized_keys` file is restored.

Of course, if your partner were sufficiently determined to break into your
system, they could still manage to do so. Our assumption here is that
*supervised* access is “reasonably secure” in most environments. If your partner
does not need write access, `tmuxpair` provides a view-only mode that should not
leave any security loopholes.

Security could be enhanced further by running the tmux session under a separate
and dedicated account instead of your normal user account. However, the purpose
of the `tmuxpair` script is to provide a robust solution that allows you to
quickly share a terminal with a colleague, *without* any further setup.


[1]: https://blog.pivotal.io/pivotal-labs/labs/how-we-use-tmux-for-remote-pair-programming
[2]: http://unix.stackexchange.com/questions/232/unix-linux-pranks
[3]: https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
[4]: https://en.m.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys
[5]: http://collectiveidea.com/blog/archives/2014/02/18/a-simple-pair-programming-setup-with-ssh-and-tmux/
41 changes: 41 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python
import setuptools


def get_version(filename):
with open(filename) as in_fh:
for line in in_fh:
if line.startswith('__version__'):
return line.split('=')[1].strip()[1:-1]
raise ValueError("Cannot extract version from %s" % filename)


setuptools.setup(
name="tmuxpair",
version=get_version("tmuxpair.py"),
url="https://github.com/goerz/tmuxpair#tmuxpair",
author="Michael Goerz",
author_email="goerz@stanford.edu",
description="Command line script for setting up a temporary tmux session for pair programming",
install_requires=[
'Click>=5', 'sshkeys>=0.5',
],
extras_require={'dev': ['pytest', 'coverage', 'pytest-cov']},
py_modules=['tmuxpair'],
entry_points='''
[console_scripts]
tmuxpair=tmuxpair:main
''',
classifiers=[
'Environment :: Console',
'Natural Language :: English',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
],
)
Loading

0 comments on commit 8a5217c

Please sign in to comment.