Created
May 22, 2012 21:23
-
-
Save stevenh512/2771702 to your computer and use it in GitHub Desktop.
GitHub Authorizations API for command line apps using Octokit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Gemfile.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
# Use Octokit 1.3.0 or higher for great justice (and Authorizations) | |
gem 'octokit', '>= 1.3.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use Octokit 1.3.0 or higher for great justice (and Authorizations) | |
require 'bundler/setup' | |
require 'octokit' | |
require 'yaml' | |
class GitHubAuth | |
# Change NOTE, SCOPES and CREDENTIALS to match your app's needs. | |
NOTE = "Octokit example" | |
SCOPES = ["user", "repo"] | |
CREDENTIALS = File.join("#{ENV['HOME']}", ".config", "sample_app.yml") | |
def self.client | |
new.client | |
end | |
def client | |
@client ||= lambda do | |
unless File.exist?(CREDENTIALS) | |
authenticate | |
end | |
Octokit::Client.new(YAML.load_file(CREDENTIALS)) | |
end.call | |
end | |
private | |
def authenticate | |
login = password = token = "" | |
login = `git config github.user`.chomp | |
login = ask_login if login.empty? | |
password = ask_password | |
auth_client = Octokit::Client.new(:login => login, :password => password) | |
auth = auth_client.authorizations.detect { |a| a.note == NOTE } | |
unless auth | |
auth = auth_client.create_authorization(:scopes => SCOPES, :note => NOTE) | |
end | |
File.open(CREDENTIALS, 'w') do |f| | |
f.puts({ :login => login, :oauth_token => auth.token }.to_yaml) | |
end | |
end | |
def ask_login | |
p "Enter your GitHub username" | |
gets.chomp | |
end | |
# No-echo password input, stolen from Defunkt's `hub` | |
# Won't work in Windows | |
def ask_password | |
p "Enter your GitHub password (this will NOT be stored)" | |
tty_state = `stty -g` | |
system 'stty raw -echo -icanon isig' if $?.success? | |
pass = '' | |
while char = $stdin.getbyte and not (char == 13 or char == 10) | |
if char == 127 or char == 8 | |
pass[-1,1] = '' unless pass.empty? | |
else | |
pass << char.chr | |
end | |
end | |
pass | |
ensure | |
system "stty #{tty_state}" unless tty_state.empty? | |
end | |
end | |
# Example | |
client = GitHubAuth.client | |
client.follows? "stevenh512" |
Hey, I'd been using this pattern but noticed it wasn't working properly for me until I made a change.
Line 9 should be SCOPES = ["user","repo"]
otherwise the authorization is generated with a malformed scope, which was causing any requests made with the token that needed scope to fail.
Good catch. When I originally wrote this I think a space separated string was acceptable for scopes, but now it seems (according to the GitHub and Octokit docs) that an array is required. I'll update that now.
Thanks :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to use Octokit 1.3.0 from RubyGems, which includes the Authorizations API 😁