forked from jwaldrip/dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup-private
executable file
·101 lines (81 loc) · 2.27 KB
/
setup-private
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env ruby
require 'net/http'
require 'net/https'
require 'json'
require 'io/console'
require 'pp'
module ShellFunctions
def ask(question, silent: false)
puts question
result = silent ? STDIN.noecho(&:gets) : gets
result.strip
end
end
class GithubToken < String
include ShellFunctions
URL = URI.parse'https://api.github.com/'
class RequestError < StandardError
def initialize(response)
super(JSON.parse(response.body)['message'])
end
end
LoginError = Class.new RequestError
MissingOneTimePasswordError = RequestError
def initialize
@attempts = 0
super(fetch)
end
private
def connection
Net::HTTP.new(URL.host, URL.port).tap { |conn| conn.use_ssl = URL.scheme == 'https' }
end
def get_password
ask "Enter github password:", silent: true
end
def get_username
ask "Enter github username:"
end
def get_otp
ask "Enter two-factor-auth code:"
end
def fetch(username: get_username, password: get_password, tfa: false)
request = Net::HTTP::Post.new('/authorizations')
request['X-GitHub-OTP'] = get_otp if tfa
request.basic_auth username, password
request.body = JSON.dump scopes: ['repo'], note: "setup #{Time.now.to_i}"
response = connection.request request
if response.code.to_i == 401
error = response['x-github-otp'] && !tfa ? MissingOneTimePasswordError : LoginError
fail error, response
end
fail RequestError, response unless response.code.to_i < 300
JSON.parse(response.body)['token']
rescue LoginError => e
@attempts += 1
@attempts > 3 ? raise(e) : warn(e)
warn "#{@attempts} failed attempts"
fetch
rescue MissingOneTimePasswordError => e
warn e
fetch(username: username, password: password, tfa: true)
end
end
class SetupPrivate
include ShellFunctions
def self.start
new.start
end
def start
return if File.exist?('.private') &&
ask(".private exists, are you sure you want to continue? y/n") != 'y'
puts "getting private directory"
system "git clone https://jwaldrip:#{token}@github.com/jwaldrip/.private"
system 'chmod 400 ~/.ssh/id_dsa &> /dev/null'
system 'chmod 400 ~/.ssh/id_rsa &> /dev/null'
end
private
def token
@token ||= GithubToken.new
end
end
SetupPrivate.start