Skip to content

Instantly share code, notes, and snippets.

@askdaddy
Created December 2, 2019 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save askdaddy/dbf54779fdf1555e0184fdc647a71aef to your computer and use it in GitHub Desktop.
Save askdaddy/dbf54779fdf1555e0184fdc647a71aef to your computer and use it in GitHub Desktop.
Import your ssh keys from github
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ssh-copy-github
===============
@author: sang
Import all your ssh keys from github to `authorized_keys`.
Performs deduplication over public keys.
# NOTE: Only Python 3 compatible
"""
from __future__ import print_function
import json
import os
from base64 import b64encode
from os.path import isfile
from os.path import join as joinpath
from urllib.error import HTTPError
from urllib.parse import urljoin, urlparse
from urllib.request import Request, urlopen
class Github(object):
"""
Simple class that interacts with the github and
manages encapsulates RESTful api endpoints.
"""
API_BASE = 'api.github.com'
USER_AGENT = 'jjangsangy/ssh-copy-github'
def __init__(self, username, token):
self.username = username
self.token = token
def __repr__(self):
return '<{!s} [{!s}:{!s}]>'.format(
self.__class__.__name__,
self.username,
self.token[:3] + 3 * '*' + self.token[-3:]
)
def get(self, path, scheme='https'):
url = urljoin(urlparse('//' + self.API_BASE, scheme=scheme).geturl(), path)
request = Request(url=url, method='GET')
request.add_header('authorization', 'Basic %s' % self.authorization)
request.add_header('user-agent', self.USER_AGENT)
return urlopen(request)
@staticmethod
def json(response):
return json.loads(response.read())
@property
def authorization(self):
basic = '{!s}:{!s}'.format(self.username, self.token)
return b64encode(bytes(basic, "utf-8")).decode('utf-8')
def get_user(self):
return self.json(self.get('user'))
def get_keys(self):
keylist = self.json(self.get('users/jjangsangy/keys'))
return {
k.get('id'): k.get('key') for k in keylist if 'id' in k and 'key' in k
}
def authorized_keys():
"""
# TODO: Graceful degredation of edge cases.
Checks that `authorized_keys` file exists within ~/.ssh
"""
home = os.environ.get('HOME')
ssh = joinpath(home, '.ssh')
authorized = joinpath(ssh, 'authorized_keys')
return authorized if isfile(authorized) else None
def main():
"""
# TODO: cli should be implemented with argparse
"""
username = input('Username: ')
token = input('Token: ')
github = Github(username, token)
git_keys = github.get_keys()
unique = set(git_keys.values()) - set(i.strip() for i in open(authorized_keys()))
for pubkey in unique:
with open(authorized_keys(), 'a+') as fp:
print(pubkey)
print(pubkey, file=fp)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment