Skip to content

Instantly share code, notes, and snippets.

@esprehn
Created November 8, 2010 00:20
Show Gist options
  • Save esprehn/667226 to your computer and use it in GitHub Desktop.
Save esprehn/667226 to your computer and use it in GitHub Desktop.
datoken
#!/usr/bin/ruby
# Tool for getting and managing deviantART auth tokens.
#
# Copyright 2009, Elliott Sprehn. (Zeros-Elipticus.deviantart.com)
#
# Licensed under the GPLv3.
# http://www.gnu.org/licenses/quick-guide-gplv3.html
#
DA_TOKEN_VERSION = "1.5"
require 'net/https'
require 'uri'
# block "warning: peer certificate won't be verified in this SSL session" messages
class Net::HTTP
alias_method :old_initialize, :initialize
def initialize(*args)
old_initialize(*args)
@ssl_context = OpenSSL::SSL::SSLContext.new
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
end
class DATokenTool
DEFAULT_TOKEN_FILE = File.expand_path("~/") + "/.datokens"
attr_reader :tokens
# Loads a file and then ensures it's saved after block executes.
# Block is passed the created token tool.
#
def self.start(file=DEFAULT_TOKEN_FILE, &block)
tool = new()
tool.load_tokens(file)
begin
yield tool
ensure
tool.store_tokens(file)
end
end
def load_tokens(file)
if File.exists?(file)
File.open(file,"r") do |f|
@tokens = Marshal.restore(f) rescue {}
end
end
@tokens ||= {}
end
def store_tokens(file)
File.open(file,"w") do |f|
Marshal.dump(@tokens,f)
end
end
# Adds a new token, optionally asking dA to generate a brand new one
# if reusetoken is false.
#
# Performs an http request against chat.deviantart.com to ensure the
# new token can be used with dAmn.
#
def add_token(username, password, reusetoken)
uri = URI.parse('https://www.deviantart.com/users/login')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == "https"
http.start {
cookie = nil
token = nil
data = URI.encode("username=#{username}&password=#{password}&reusetoken=#{reusetoken and 1 or 0}")
http.request_post(uri.path,data) {|res|
if( res.get_fields('location') and
res.get_fields('location')[0] == 'http://www.deviantart.com/users/loggedin' and
(token = URI.decode(res['Set-Cookie']).match('"authtoken";s:32:"([a-f0-9]{32})";')))
cookie = res['Set-Cookie']
# Make cookie usable in dAmn.
enable_token(cookie) if cookie
@tokens[username] = token[1]
return token[1]
end
}
}
nil
end
private
# Enables a token's use with dAmn.
#
def enable_token(cookie)
uri = URI.parse('http://chat.deviantart.com/chat/devart')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == "https"
http.start { |http|
request = Net::HTTP::Get.new(uri.path)
request['Cookie'] = cookie
response = http.request(request)
}
end
end
module Prompt
def self.prompt(text)
print text
$stdin.gets.chomp
end
# Promps for text, but hides what the user types.
#
def self.prompt_hidden(text)
stty_orig = `stty -g`
`stty -echo`
password = prompt(text)
puts
`stty #{stty_orig}`
password
end
end
DATokenTool.start do |tokentool|
if ARGV.empty? or ARGV[0] == 'list'
if tokentool.tokens.empty?
puts "No tokens have been added."
else
puts "Tokens:"
tokentool.tokens.sort.each do |username,token|
puts "\t#{username}: #{token}"
end
end
elsif ARGV[0] == "new" or ARGV[0] == "add"
username = ARGV[1].dup or Prompt.prompt("Username: ")
password = Prompt.prompt_hidden("Password: ")
username.downcase!
if tokentool.add_token(username, password, ARGV[0] != "new")
puts "Token: " + tokentool.tokens[username]
else
puts "Invalid password."
end
elsif ARGV[0] == "remove"
username = ARGV[1] or Prompt.prompt("Username: ")
tokentool.tokens.delete(username.downcase)
else
puts "deviantART Authtoken Tool #{DA_TOKEN_VERSION} by Zeros-Elipticus"
puts "Usage:"
puts "\tdatoken list List all tokens (default)"
puts "\tdatoken help Show this info"
puts "\tdatoken add [username] Add and resuse the old token"
puts "\tdatoken new [username] Add and generate new token"
puts "\tdatoken remove [username] Remove token from list"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment