#!/usr/bin/env ruby $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require "rack/oauth2/server" require "uri" include Rack::OAuth2 if (i = ARGV.index("--db")) && ARGV[i+1] url = ARGV[i + 1] uri = URI.parse(url) uri = URI.parse("mongo://#{url}") if uri.opaque db = Mongo::Connection.new(uri.host, uri.port)[uri.path.sub(/^\//, "")] db.authenticate uri.user, uri.password if uri.user Server.options.database = db ARGV[i,2] = [] end if (i = ARGV.index("--port") || ARGV.index("-p")) && ARGV[i+1] port = ARGV[i + 1].to_i ARGV[i,2] = [] end if (i = ARGV.index("--collection-prefix") || ARGV.index("-c")) && ARGV[i+1] prefix = ARGV[i + 1] Server.options.collection_prefix = prefix ARGV[i,2] = [] else Server.options.collection_prefix = 'oauth2' end case ARGV[0] when "list" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database Server::Client.all.each do |client| next if client.revoked print "%-30s\t%s\n" % [client.display_name, client.link] print " ID %s\tSecret %s\n" % [client.id, client.secret] print "\n" end when "register" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database begin print "Application name:\t" display_name = $stdin.gets print "Application URL:\t" link = $stdin.gets print "Redirect URI:\t\t" redirect_uri = $stdin.gets print "Scope (space separated names):\t\t" scope = $stdin.gets client = Server.register(:display_name=>display_name, :link=>link, :redirect_uri=>redirect_uri, :scope=>scope) rescue puts "\nFailed to register client: #{$!}" exit -1 end puts "Registered #{client.display_name}" puts "ID\t#{client.id}" puts "Secret\t#{client.secret}" when "register_issuer" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database begin print "Identifier (typically a URL):\t" identifier = $stdin.gets print "HMAC secret:\t" hmac_secret = $stdin.gets print "RSA public key:\t\t" public_key = $stdin.gets issuer = Server.register_issuer(:identifier => identifier, :hmac_secret => hmac_secret, :public_key => public_key) rescue puts "\nFailed to register issuer: #{$!}" exit -1 end puts "Registered Issuer #{issuer.identifier}" puts "HMAC secret\t#{issuer.hmac_secret}" puts "RSA public key\t#{issuer.public_key}" when "setup" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database puts "Where would you mount the Web console? This is a URL that must end with /admin," puts "for example, http://example.com/oauth/admin" print ": " uri = URI.parse($stdin.gets) begin uri.normalize! fail "No an HTTP/S URL" unless uri.absolute? && %{http https}.include?(uri.scheme) fail "Path must end with /admin" unless uri.path[/\/admin$/] client = Server.register(:display_name=>"OAuth Console", :link=>uri.to_s, :image_url=>"#{uri.to_s}/images/oauth-2.png", :redirect_uri=>uri.to_s, :scope=>"oauth-admin") rescue puts "\nFailed to register client: #{$!}" exit -1 end print <<-TEXT Next Steps ========== Make sure you ONLY authorize administrators to use the oauth-admin scope. For example: before_filter do # Only admins allowed to authorize the scope oauth-admin head oauth.deny! if oauth.scope.include?("oauth-admin") && !current_user.admin? end Rails 2.x, add the following to config/environment.rb: config.after_initialize do config.middleware.use Rack::OAuth2::Server::Admin.mount "#{uri.path}" Rack::OAuth2::Server::Admin.set :client_id, "#{client.id}" Rack::OAuth2::Server::Admin.set :client_secret, "#{client.secret}" end Rails 3.x, add the following to config/application.rb: config.after_initialize do Rack::OAuth2::Server::Admin.set :client_id, "#{client.id}" Rack::OAuth2::Server::Admin.set :client_secret, "#{client.secret}" end And add the follownig to config/routes.rb: mount Rack::OAuth2::Server::Admin=>"/oauth/admin" Sinatra, Padrino and other Rack applications, mount the console: Rack::Builder.new do map("#{uri.path}") { run Rack::OAuth2::Server::Admin } map("/") { run MyApp } end Rack::OAuth2::Server::Admin.set :client_id, "#{client.id}" Rack::OAuth2::Server::Admin.set :client_secret, "#{client.secret}" The console will authorize access by redirecting to https://#{uri.host}/oauth/authorize If this is not your OAuth 2.0 authorization endpoint, you can change it by setting the :authorize option. TEXT when "practice" require "logger" begin require "thin" rescue LoadError puts "Needs the Thin Web server. Please gem install thin and run again" exit -1 end require "rack/oauth2/server/practice" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database port ||= 8080 admin_url = "http://localhost:#{port}/oauth/admin" unless client = Server::Client.lookup(admin_url) client = Server.register(:display_name=>"Practice OAuth Console", :image_url=>"#{admin_url}/images/oauth-2.png", :link=>admin_url, :redirect_uri=>admin_url, :scope=>"oauth-admin") end Server::Admin.configure do |config| logger = Logger.new(STDOUT) logger.level = Logger::DEBUG config.set :client_id, client.id config.set :client_secret, client.secret config.set :scope, "nobody sudo" config.set :logger, logger config.set :logging, true config.set :dump_errors, true config.oauth.logger = logger end Server::Practice.configure do |config| logger = Logger.new(STDOUT) logger.level = Logger::DEBUG config.set :logger, logger config.set :logging, true config.set :dump_errors, true config.oauth.logger = logger end print "\nFiring up the practice server.\nFor instructions, go to http://localhost:#{port}/\n\n\n" Thin::Server.new "127.0.0.1", port do map("/") { run Server::Practice.new } map("/oauth/admin") { run Server::Admin.new } end.start when "migrate" fail "No database. Use the --db option to tell us which database to use" unless Server.options.database puts "Set all clients to this scope (can change later by calling Client.register):" print ": " scope = $stdin.gets.strip.split puts "Updating Client scope to #{scope.join(", ")}" Server::Client.collection.find({ :scope=>{ :$exists=>false } }, :fields=>[]).each do |client| update = { :scope=>scope, :tokens_granted=>Server::AccessToken.count(:client_id=>client["_id"]), :tokens_revoked=>Server::AccessToken.count(:client_id=>client["_id"], :revoked=>true) } Server::Client.collection.update({ :_id=>client["_id"] }, { :$set=>update }) end [Server::AccessToken, Server::AccessGrant, Server::AuthRequest].each do |mod| puts "Updating #{mod.name} scope from string to array" mod.collection.find({ :scope=>{ :$type=>2 } }, :fields=>[]).each do |token| scope = token["scope"].split mod.collection.update({ :_id=>token["_id"] }, { :$set=>{ :scope=>scope } }) end end else print <<-TEXT Usage: oauth2-server [options] COMMAND [args] Version #{Server::VERSION} Commands: list Lists all active clients migrate Run this when migrating from 1.x to 2.x practice Runs a dummy OAuth 2.0 server, use this to test your OAuth 2.0 client register Register a new client application register_issuer Register a new assertion issuer setup Create new admin account and help you setup the OAuth Web console Options: --db database Database name or connection URL --port number Port to run admin server, detault is 8080 --collection-prefix Prefix to use for MongoDB collections created by rack-oauth2-server, defaults to "oauth2". TEXT exit -1 end