gist 4.6.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +43 -10
- data/Rakefile +1 -3
- data/bin/gist +19 -12
- data/gist.gemspec +1 -1
- data/lib/gist.rb +115 -38
- data/spec/ghe_spec.rb +12 -5
- data/spec/rawify_spec.rb +10 -1
- data/spec/shorten_spec.rb +11 -2
- data/spec/spec_helper.rb +1 -1
- metadata +3 -8
- data/.gitignore +0 -8
- data/build/gist +0 -2357
- data/build/gist.1 +0 -258
- data/vendor/netrc.rb +0 -286
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 78e3d009d0e3e3a535d20e8d7e0582705c6ea61308958c3f59a4d4a2e365fa3c
|
4
|
+
data.tar.gz: 23df778298090151ce7e2b8f3dbb8f97786bc7d576f218be1aeb454123090e91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70506cc45562b725085e2f10d5627a3ac4c700fa6e599e39a6625629fbd2c63903b2d42a4a95d9642f0ac01893bd8de27d72acb7e4622eaa44ab4ea96b08840c
|
7
|
+
data.tar.gz: b3476f46cb844603a169e3a67fae3bb37e5399494ddec6c78178f4bb664a90cda642c5be780ea007d12e96cc96312f695b86827872bc4947603c092a4e3d6774
|
data/README.md
CHANGED
@@ -21,6 +21,11 @@ upload content to https://gist.github.com/.
|
|
21
21
|
|
22
22
|
brew install gist
|
23
23
|
|
24
|
+
For FreeBSD, gist lives in ports
|
25
|
+
|
26
|
+
pkg install gist
|
27
|
+
|
28
|
+
|
24
29
|
## Command
|
25
30
|
|
26
31
|
To upload the contents of `a.rb` just:
|
@@ -79,12 +84,29 @@ To read a gist and print it to STDOUT
|
|
79
84
|
|
80
85
|
## Login
|
81
86
|
|
82
|
-
|
83
|
-
|
84
|
-
an
|
87
|
+
Before you use `gist` for the first time you will need to log in. There are two supported login flows:
|
88
|
+
|
89
|
+
1. The Github device-code Oauth flow. This is the default for authenticating to github.com, and can be enabled for Github Enterprise by creating an Oauth app, and exporting the environment variable `GIST_CLIENT_ID` with the client id of the Oauth app.
|
90
|
+
2. The (deprecated) username and password token exchange flow. This is the default for GitHub Enterprise, and can be used to log into github.com by exporting the environment variable `GIST_USE_USERNAME_AND_PASSWORD`.
|
91
|
+
|
92
|
+
### The device-code flow
|
93
|
+
|
94
|
+
This flow allows you to obtain a token by logging into GitHub in the browser and typing a verification code. This is the preferred mechanism.
|
85
95
|
|
86
96
|
gist --login
|
87
|
-
|
97
|
+
Requesting login parameters...
|
98
|
+
Please sign in at https://github.com/login/device
|
99
|
+
and enter code: XXXX-XXXX
|
100
|
+
Success! https://github.com/settings/connections/applications/4f7ec0d4eab38e74384e
|
101
|
+
|
102
|
+
The returned access_token is stored in `~/.gist` and used for all future gisting. If you need to you can revoke access from https://github.com/settings/connections/applications/4f7ec0d4eab38e74384e.
|
103
|
+
|
104
|
+
### The username-password flow
|
105
|
+
|
106
|
+
This flow asks for your GitHub username and password (and 2FA code), and exchanges them for a token with the "gist" permission (your username and password are not stored). This mechanism is deprecated by GitHub, but may still work with GitHub Enterprise.
|
107
|
+
|
108
|
+
gist --login
|
109
|
+
Obtaining OAuth2 access_token from GitHub.
|
88
110
|
GitHub username: ConradIrwin
|
89
111
|
GitHub password:
|
90
112
|
2-factor auth code:
|
@@ -94,9 +116,21 @@ This token is stored in `~/.gist` and used for all future gisting. If you need t
|
|
94
116
|
you can revoke it from https://github.com/settings/tokens, or just delete the
|
95
117
|
file.
|
96
118
|
|
97
|
-
|
119
|
+
#### Password-less login
|
120
|
+
|
121
|
+
If you have a complicated authorization requirement you can manually create a
|
122
|
+
token file by pasting a GitHub token with `gist` scope (and maybe the `user:email`
|
123
|
+
for GitHub Enterprise) into a file called `~/.gist`. You can create one from
|
124
|
+
https://github.com/settings/tokens
|
125
|
+
|
126
|
+
This file should contain only the token (~40 hex characters), and to make it
|
127
|
+
easier to edit, can optionally have a final newline (`\n` or `\r\n`).
|
128
|
+
|
129
|
+
For example, one way to create this file would be to run:
|
130
|
+
|
131
|
+
(umask 0077 && echo MY_SECRET_TOKEN > ~/.gist)
|
98
132
|
|
99
|
-
|
133
|
+
The `umask` ensures that the file is only accessible from your user account.
|
100
134
|
|
101
135
|
### GitHub Enterprise
|
102
136
|
|
@@ -106,10 +140,10 @@ you need to export the `GITHUB_URL` environment variable (usually done in your `
|
|
106
140
|
export GITHUB_URL=http://github.internal.example.com/
|
107
141
|
|
108
142
|
Once you've done this and restarted your terminal (or run `source ~/.bashrc`), gist will
|
109
|
-
automatically use
|
143
|
+
automatically use GitHub Enterprise instead of the public github.com
|
110
144
|
|
111
145
|
Your token for GitHub Enterprise will be stored in `.gist.<protocol>.<server.name>[.<port>]` (e.g.
|
112
|
-
|
146
|
+
`~/.gist.http.github.internal.example.com` for the GITHUB_URL example above) instead of `~/.gist`.
|
113
147
|
|
114
148
|
If you have multiple servers or use Enterprise and public GitHub often, you can work around this by creating scripts
|
115
149
|
that set the env var and then run `gist`. Keep in mind that to use the public GitHub you must unset the env var. Just
|
@@ -137,11 +171,10 @@ If you need more advanced features you can also pass:
|
|
137
171
|
* `:public` if you want your gist to have a guessable url.
|
138
172
|
* `:description` to add a description to your gist.
|
139
173
|
* `:update` to update an existing gist (can be a URL or an id).
|
140
|
-
* `:anonymous` to submit an anonymous gist (default is false).
|
141
174
|
* `:copy` to copy the resulting URL to the clipboard (default is false).
|
142
175
|
* `:open` to open the resulting URL in a browser (default is false).
|
143
176
|
|
144
|
-
NOTE: The access_token must have the
|
177
|
+
NOTE: The access_token must have the `gist` scope and may also require the `user:email` scope.
|
145
178
|
|
146
179
|
If you want to upload multiple files in the same gist, you can:
|
147
180
|
|
data/Rakefile
CHANGED
@@ -23,9 +23,7 @@ task :standalone do
|
|
23
23
|
f.puts "#!/usr/bin/env ruby"
|
24
24
|
f.puts "# This is generated from https://github.com/defunkt/gist using 'rake standalone'"
|
25
25
|
f.puts "# any changes will be overwritten."
|
26
|
-
f.puts File.read("lib/gist.rb")
|
27
|
-
.split("require 'json'\n").join(File.read("vendor/json.rb"))
|
28
|
-
.split("require 'netrc'\n").join(File.read("vendor/netrc.rb"))
|
26
|
+
f.puts File.read("lib/gist.rb").split("require 'json'\n").join(File.read("vendor/json.rb"))
|
29
27
|
|
30
28
|
f.puts File.read("bin/gist").gsub(/^require.*gist.*\n/, '');
|
31
29
|
end
|
data/bin/gist
CHANGED
@@ -24,16 +24,12 @@ specified STDIN will be read. The default filename for STDIN is "a.rb", and all
|
|
24
24
|
filenames can be overridden by repeating the "-f" flag. The most useful reason
|
25
25
|
to do this is to change the syntax highlighting.
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
Oauth2 access token. This is stored and used by gist in the future.
|
27
|
+
All gists must to be associated with a GitHub account, so you will need to login with
|
28
|
+
`gist --login` to obtain an OAuth2 access token. This is stored and used by gist in the future.
|
30
29
|
|
31
30
|
Private gists do not have guessable URLs and can be created with "-p", you can
|
32
31
|
also set the description at the top of the gist by passing "-d".
|
33
32
|
|
34
|
-
Anonymous gists are not associated with your GitHub account, they can be created
|
35
|
-
with "-a" even after you have used "gist --login".
|
36
|
-
|
37
33
|
If you would like to shorten the resulting gist URL, use the -s flag. This will
|
38
34
|
use GitHub's URL shortener, git.io. You can also use -R to get the link to the
|
39
35
|
raw gist.
|
@@ -47,7 +43,11 @@ Instead of creating a new gist, you can update an existing one by passing its ID
|
|
47
43
|
or URL with "-u". For this to work, you must be logged in, and have created the
|
48
44
|
original gist with the same GitHub account.
|
49
45
|
|
50
|
-
|
46
|
+
If you want to skip empty files, use the --skip-empty flag. If all files are
|
47
|
+
empty no gist will be created.
|
48
|
+
|
49
|
+
Usage: #{executable_name} [-o|-c|-e] [-p] [-s] [-R] [-d DESC] [-u URL]
|
50
|
+
[--skip-empty] [-P] [-f NAME|-t EXT]* FILE*
|
51
51
|
#{executable_name} --login
|
52
52
|
#{executable_name} [-l|-r]
|
53
53
|
|
@@ -88,10 +88,6 @@ Usage: #{executable_name} [-o|-c|-e] [-p] [-s] [-R] [-d DESC] [-a] [-u URL] [-P]
|
|
88
88
|
options[:update] = update
|
89
89
|
end
|
90
90
|
|
91
|
-
opts.on("-a", "--anonymous", "Create an anonymous gist.") do
|
92
|
-
options[:anonymous] = true
|
93
|
-
end
|
94
|
-
|
95
91
|
opts.on("-c", "--copy", "Copy the resulting URL to the clipboard") do
|
96
92
|
options[:copy] = true
|
97
93
|
end
|
@@ -107,6 +103,10 @@ Usage: #{executable_name} [-o|-c|-e] [-p] [-s] [-R] [-d DESC] [-a] [-u URL] [-P]
|
|
107
103
|
|
108
104
|
opts.on("--no-open")
|
109
105
|
|
106
|
+
opts.on("--skip-empty", "Skip gisting empty files") do
|
107
|
+
options[:skip_empty] = true
|
108
|
+
end
|
109
|
+
|
110
110
|
opts.on("-P", "--paste", "Paste from the clipboard to gist") do
|
111
111
|
options[:paste] = true
|
112
112
|
end
|
@@ -140,6 +140,12 @@ Usage: #{executable_name} [-o|-c|-e] [-p] [-s] [-R] [-d DESC] [-a] [-u URL] [-P]
|
|
140
140
|
end.parse!
|
141
141
|
|
142
142
|
begin
|
143
|
+
if Gist.auth_token.nil?
|
144
|
+
puts 'Please log in with `gist --login`. ' \
|
145
|
+
'(GitHub now requires credentials to gist https://bit.ly/2GBBxKw)'
|
146
|
+
exit(1)
|
147
|
+
end
|
148
|
+
|
143
149
|
options[:output] = if options[:embed] && options[:shorten]
|
144
150
|
raise Gist::Error, "--embed does not make sense with --shorten"
|
145
151
|
elsif options[:embed]
|
@@ -195,7 +201,8 @@ begin
|
|
195
201
|
end
|
196
202
|
end
|
197
203
|
|
198
|
-
|
204
|
+
output = Gist.multi_gist(files, options)
|
205
|
+
puts output if output
|
199
206
|
end
|
200
207
|
|
201
208
|
rescue Gist::Error => e
|
data/gist.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ['conrad.irwin@gmail.com', 'rkingist@sharpsaw.org']
|
10
10
|
s.authors = ['Conrad Irwin', '☈king']
|
11
11
|
s.license = 'MIT'
|
12
|
-
s.files = `git ls-files`.split("\n")
|
12
|
+
s.files = `git ls-files`.split("\n") - Dir.glob("build/*") - [".gitignore"]
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
|
15
15
|
s.executables << 'gist'
|
data/lib/gist.rb
CHANGED
@@ -8,17 +8,11 @@ rescue LoadError
|
|
8
8
|
require File.join File.dirname(File.dirname(__FILE__)), 'vendor', 'json.rb'
|
9
9
|
end
|
10
10
|
|
11
|
-
begin
|
12
|
-
require 'netrc'
|
13
|
-
rescue LoadError
|
14
|
-
require File.join File.dirname(File.dirname(__FILE__)), 'vendor', 'netrc.rb'
|
15
|
-
end
|
16
|
-
|
17
11
|
# It just gists.
|
18
12
|
module Gist
|
19
13
|
extend self
|
20
14
|
|
21
|
-
VERSION = '
|
15
|
+
VERSION = '6.0.0'
|
22
16
|
|
23
17
|
# A list of clipboard commands with copy and paste support.
|
24
18
|
CLIPBOARD_COMMANDS = {
|
@@ -29,12 +23,16 @@ module Gist
|
|
29
23
|
}
|
30
24
|
|
31
25
|
GITHUB_API_URL = URI("https://api.github.com/")
|
26
|
+
GITHUB_URL = URI("https://github.com/")
|
32
27
|
GIT_IO_URL = URI("https://git.io")
|
33
28
|
|
34
29
|
GITHUB_BASE_PATH = ""
|
35
30
|
GHE_BASE_PATH = "/api/v3"
|
36
31
|
|
32
|
+
GITHUB_CLIENT_ID = '4f7ec0d4eab38e74384e'
|
33
|
+
|
37
34
|
URL_ENV_NAME = "GITHUB_URL"
|
35
|
+
CLIENT_ID_ENV_NAME = "GIST_CLIENT_ID"
|
38
36
|
|
39
37
|
USER_AGENT = "gist/#{VERSION} (Net::HTTP, #{RUBY_DESCRIPTION})"
|
40
38
|
|
@@ -50,7 +48,7 @@ module Gist
|
|
50
48
|
module AuthTokenFile
|
51
49
|
def self.filename
|
52
50
|
if ENV.key?(URL_ENV_NAME)
|
53
|
-
File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/:/, '.').gsub(/[^a-z0-9
|
51
|
+
File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/:/, '.').gsub(/[^a-z0-9.-]/, '')}"
|
54
52
|
else
|
55
53
|
File.expand_path "~/.gist"
|
56
54
|
end
|
@@ -71,7 +69,7 @@ module Gist
|
|
71
69
|
#
|
72
70
|
# @return [String] string value of access token or `nil`, if not found
|
73
71
|
def auth_token
|
74
|
-
@token ||= AuthTokenFile.read rescue nil
|
72
|
+
@token ||= AuthTokenFile.read rescue nil
|
75
73
|
end
|
76
74
|
|
77
75
|
# Upload a gist to https://gist.github.com
|
@@ -82,10 +80,14 @@ module Gist
|
|
82
80
|
#
|
83
81
|
# @see http://developer.github.com/v3/gists/
|
84
82
|
def gist(content, options = {})
|
85
|
-
filename = options[:filename] ||
|
83
|
+
filename = options[:filename] || default_filename
|
86
84
|
multi_gist({filename => content}, options)
|
87
85
|
end
|
88
86
|
|
87
|
+
def default_filename
|
88
|
+
"gistfile1.txt"
|
89
|
+
end
|
90
|
+
|
89
91
|
# Upload a gist to https://gist.github.com
|
90
92
|
#
|
91
93
|
# @param [Hash] files the code you'd like to gist: filename => content
|
@@ -98,6 +100,7 @@ module Gist
|
|
98
100
|
# @option options [String] :update the URL or id of a gist to update
|
99
101
|
# @option options [Boolean] :copy (false) Copy resulting URL to clipboard, if successful.
|
100
102
|
# @option options [Boolean] :open (false) Open the resulting URL in a browser.
|
103
|
+
# @option options [Boolean] :skip_empty (false) Skip gisting empty files.
|
101
104
|
# @option options [Symbol] :output (:all) The type of return value you'd like:
|
102
105
|
# :html_url gives a String containing the url to the gist in a browser
|
103
106
|
# :short_url gives a String contianing a git.io url that redirects to html_url
|
@@ -109,6 +112,13 @@ module Gist
|
|
109
112
|
#
|
110
113
|
# @see http://developer.github.com/v3/gists/
|
111
114
|
def multi_gist(files, options={})
|
115
|
+
if options[:anonymous]
|
116
|
+
raise 'Anonymous gists are no longer supported. Please log in with `gist --login`. ' \
|
117
|
+
'(GitHub now requires credentials to gist https://bit.ly/2GBBxKw)'
|
118
|
+
else
|
119
|
+
access_token = (options[:access_token] || auth_token())
|
120
|
+
end
|
121
|
+
|
112
122
|
json = {}
|
113
123
|
|
114
124
|
json[:description] = options[:description] if options[:description]
|
@@ -116,22 +126,23 @@ module Gist
|
|
116
126
|
json[:files] = {}
|
117
127
|
|
118
128
|
files.each_pair do |(name, content)|
|
119
|
-
|
120
|
-
|
129
|
+
if content.to_s.strip == ""
|
130
|
+
raise "Cannot gist empty files" unless options[:skip_empty]
|
131
|
+
else
|
132
|
+
name = name == "-" ? default_filename : File.basename(name)
|
133
|
+
json[:files][name] = {:content => content}
|
134
|
+
end
|
121
135
|
end
|
122
136
|
|
137
|
+
return if json[:files].empty? && options[:skip_empty]
|
138
|
+
|
123
139
|
existing_gist = options[:update].to_s.split("/").last
|
124
|
-
if options[:anonymous]
|
125
|
-
access_token = nil
|
126
|
-
else
|
127
|
-
access_token = (options[:access_token] || auth_token())
|
128
|
-
end
|
129
140
|
|
130
141
|
url = "#{base_path}/gists"
|
131
142
|
url << "/" << CGI.escape(existing_gist) if existing_gist.to_s != ''
|
132
|
-
url << "?access_token=" << CGI.escape(access_token) if access_token.to_s != ''
|
133
143
|
|
134
144
|
request = Net::HTTP::Post.new(url)
|
145
|
+
request['Authorization'] = "token #{access_token}" if access_token.to_s != ''
|
135
146
|
request.body = JSON.dump(json)
|
136
147
|
request.content_type = 'application/json'
|
137
148
|
|
@@ -167,9 +178,10 @@ module Gist
|
|
167
178
|
if user == ""
|
168
179
|
access_token = auth_token()
|
169
180
|
if access_token.to_s != ''
|
170
|
-
url << "/gists
|
181
|
+
url << "/gists"
|
171
182
|
|
172
183
|
request = Net::HTTP::Get.new(url)
|
184
|
+
request['Authorization'] = "token #{access_token}"
|
173
185
|
response = http(api_url, request)
|
174
186
|
|
175
187
|
pretty_gist(response)
|
@@ -192,24 +204,21 @@ module Gist
|
|
192
204
|
url = "#{base_path}"
|
193
205
|
|
194
206
|
if user == ""
|
195
|
-
|
196
|
-
if access_token.to_s != ''
|
197
|
-
url << "/gists?per_page=100&access_token=" << CGI.escape(access_token)
|
198
|
-
get_gist_pages(url)
|
199
|
-
else
|
200
|
-
raise Error, "Not authenticated. Use 'gist --login' to login or 'gist -l username' to view public gists."
|
201
|
-
end
|
202
|
-
|
207
|
+
url << "/gists?per_page=100"
|
203
208
|
else
|
204
209
|
url << "/users/#{user}/gists?per_page=100"
|
205
|
-
get_gist_pages(url)
|
206
210
|
end
|
207
211
|
|
212
|
+
get_gist_pages(url, auth_token())
|
208
213
|
end
|
209
214
|
|
210
215
|
def read_gist(id, file_name=nil)
|
211
216
|
url = "#{base_path}/gists/#{id}"
|
217
|
+
|
218
|
+
access_token = auth_token()
|
219
|
+
|
212
220
|
request = Net::HTTP::Get.new(url)
|
221
|
+
request['Authorization'] = "token #{access_token}" if access_token.to_s != ''
|
213
222
|
response = http(api_url, request)
|
214
223
|
|
215
224
|
if response.code == '200'
|
@@ -235,9 +244,8 @@ module Gist
|
|
235
244
|
|
236
245
|
access_token = auth_token()
|
237
246
|
if access_token.to_s != ''
|
238
|
-
url << "?access_token=" << CGI.escape(access_token)
|
239
|
-
|
240
247
|
request = Net::HTTP::Delete.new(url)
|
248
|
+
request["Authorization"] = "token #{access_token}"
|
241
249
|
response = http(api_url, request)
|
242
250
|
else
|
243
251
|
raise Error, "Not authenticated. Use 'gist --login' to login."
|
@@ -250,9 +258,10 @@ module Gist
|
|
250
258
|
end
|
251
259
|
end
|
252
260
|
|
253
|
-
def get_gist_pages(url)
|
261
|
+
def get_gist_pages(url, access_token = "")
|
254
262
|
|
255
263
|
request = Net::HTTP::Get.new(url)
|
264
|
+
request['Authorization'] = "token #{access_token}" if access_token.to_s != ''
|
256
265
|
response = http(api_url, request)
|
257
266
|
pretty_gist(response)
|
258
267
|
|
@@ -260,7 +269,7 @@ module Gist
|
|
260
269
|
|
261
270
|
if link_header
|
262
271
|
links = Hash[ link_header.gsub(/(<|>|")/, "").split(',').map { |link| link.split('; rel=') } ].invert
|
263
|
-
get_gist_pages(links['next']) if links['next']
|
272
|
+
get_gist_pages(links['next'], access_token) if links['next']
|
264
273
|
end
|
265
274
|
|
266
275
|
end
|
@@ -324,16 +333,72 @@ module Gist
|
|
324
333
|
|
325
334
|
# Log the user into gist.
|
326
335
|
#
|
336
|
+
def login!(credentials={})
|
337
|
+
if (login_url == GITHUB_URL || ENV.key?(CLIENT_ID_ENV_NAME)) && credentials.empty? && !ENV.key?('GIST_USE_USERNAME_AND_PASSWORD')
|
338
|
+
device_flow_login!
|
339
|
+
else
|
340
|
+
access_token_login!(credentials)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def device_flow_login!
|
345
|
+
puts "Requesting login parameters..."
|
346
|
+
request = Net::HTTP::Post.new("/login/device/code")
|
347
|
+
request.body = JSON.dump({
|
348
|
+
:scope => 'gist',
|
349
|
+
:client_id => client_id,
|
350
|
+
})
|
351
|
+
request.content_type = 'application/json'
|
352
|
+
request['accept'] = "application/json"
|
353
|
+
response = http(login_url, request)
|
354
|
+
|
355
|
+
if response.code != '200'
|
356
|
+
raise Error, "HTTP #{response.code}: #{response.body}"
|
357
|
+
end
|
358
|
+
|
359
|
+
body = JSON.parse(response.body)
|
360
|
+
|
361
|
+
puts "Please sign in at #{body['verification_uri']}"
|
362
|
+
puts " and enter code: #{body['user_code']}"
|
363
|
+
device_code = body['device_code']
|
364
|
+
interval = body['interval']
|
365
|
+
|
366
|
+
loop do
|
367
|
+
sleep(interval.to_i)
|
368
|
+
request = Net::HTTP::Post.new("/login/oauth/access_token")
|
369
|
+
request.body = JSON.dump({
|
370
|
+
:client_id => client_id,
|
371
|
+
:grant_type => 'urn:ietf:params:oauth:grant-type:device_code',
|
372
|
+
:device_code => device_code
|
373
|
+
})
|
374
|
+
request.content_type = 'application/json'
|
375
|
+
request['Accept'] = 'application/json'
|
376
|
+
response = http(login_url, request)
|
377
|
+
if response.code != '200'
|
378
|
+
raise Error, "HTTP #{response.code}: #{response.body}"
|
379
|
+
end
|
380
|
+
body = JSON.parse(response.body)
|
381
|
+
break unless body['error'] == 'authorization_pending'
|
382
|
+
end
|
383
|
+
|
384
|
+
if body['error']
|
385
|
+
raise Error, body['error_description']
|
386
|
+
end
|
387
|
+
|
388
|
+
AuthTokenFile.write JSON.parse(response.body)['access_token']
|
389
|
+
|
390
|
+
puts "Success! #{ENV[URL_ENV_NAME] || "https://github.com/"}settings/connections/applications/#{client_id}"
|
391
|
+
end
|
392
|
+
|
393
|
+
# Logs the user into gist.
|
394
|
+
#
|
327
395
|
# This method asks the user for a username and password, and tries to obtain
|
328
396
|
# and OAuth2 access token, which is then stored in ~/.gist
|
329
397
|
#
|
330
398
|
# @raise [Gist::Error] if something went wrong
|
331
|
-
# @param [Hash] credentials login details
|
332
|
-
# @option credentials [String] :username
|
333
|
-
# @option credentials [String] :password
|
334
399
|
# @see http://developer.github.com/v3/oauth/
|
335
|
-
def
|
336
|
-
puts "Obtaining OAuth2 access_token from
|
400
|
+
def access_token_login!(credentials={})
|
401
|
+
puts "Obtaining OAuth2 access_token from GitHub."
|
337
402
|
loop do
|
338
403
|
print "GitHub username: "
|
339
404
|
username = credentials[:username] || $stdin.gets.strip
|
@@ -389,7 +454,11 @@ module Gist
|
|
389
454
|
env = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
390
455
|
connection = if env
|
391
456
|
proxy = URI(env)
|
392
|
-
|
457
|
+
if proxy.user
|
458
|
+
Net::HTTP::Proxy(proxy.host, proxy.port, proxy.user, proxy.password).new(uri.host, uri.port)
|
459
|
+
else
|
460
|
+
Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port)
|
461
|
+
end
|
393
462
|
else
|
394
463
|
Net::HTTP.new(uri.host, uri.port)
|
395
464
|
end
|
@@ -543,11 +612,19 @@ Could not find copy command, tried:
|
|
543
612
|
ENV.key?(URL_ENV_NAME) ? GHE_BASE_PATH : GITHUB_BASE_PATH
|
544
613
|
end
|
545
614
|
|
615
|
+
def login_url
|
616
|
+
ENV.key?(URL_ENV_NAME) ? URI(ENV[URL_ENV_NAME]) : GITHUB_URL
|
617
|
+
end
|
618
|
+
|
546
619
|
# Get the API URL
|
547
620
|
def api_url
|
548
621
|
ENV.key?(URL_ENV_NAME) ? URI(ENV[URL_ENV_NAME]) : GITHUB_API_URL
|
549
622
|
end
|
550
623
|
|
624
|
+
def client_id
|
625
|
+
ENV.key?(CLIENT_ID_ENV_NAME) ? URI(ENV[CLIENT_ID_ENV_NAME]) : GITHUB_CLIENT_ID
|
626
|
+
end
|
627
|
+
|
551
628
|
def legacy_private_gister?
|
552
629
|
return unless which('git')
|
553
630
|
`git config --global gist.private` =~ /\Ayes|1|true|on\z/i
|