Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

remove obsolete gem code

[fixes #43896637]
  • Loading branch information...
commit eecfb7dd41e23bad42877ae0f3bc4a1bc6dd9842 1 parent 45072bc
@daleolds daleolds authored
Showing with 1 addition and 5,086 deletions.
  1. +0 −16 gem/Gemfile
  2. +1 −55 gem/README.md
  3. +0 −50 gem/Rakefile
  4. +0 −80 gem/bin/completion-helper
  5. +0 −5 gem/bin/uaac
  6. +0 −34 gem/bin/uaac-completion.sh
  7. +0 −8 gem/bin/uaas
  8. +0 −48 gem/cf-uaa-client.gemspec
  9. +0 −14 gem/lib/cli.rb
  10. +0 −274 gem/lib/cli/base.rb
  11. +0 −104 gem/lib/cli/client_reg.rb
  12. +0 −180 gem/lib/cli/common.rb
  13. +0 −163 gem/lib/cli/config.rb
  14. BIN  gem/lib/cli/favicon.ico
  15. +0 −88 gem/lib/cli/group.rb
  16. +0 −54 gem/lib/cli/info.rb
  17. +0 −49 gem/lib/cli/runner.rb
  18. +0 −294 gem/lib/cli/stub_server.rb
  19. +0 −217 gem/lib/cli/token.rb
  20. +0 −120 gem/lib/cli/user.rb
  21. +0 −19 gem/lib/uaa.rb
  22. +0 −77 gem/lib/uaa/client_reg.rb
  23. +0 −160 gem/lib/uaa/http.rb
  24. +0 −104 gem/lib/uaa/misc.rb
  25. +0 −149 gem/lib/uaa/token_coder.rb
  26. +0 −179 gem/lib/uaa/token_issuer.rb
  27. +0 −146 gem/lib/uaa/user_account.rb
  28. +0 −110 gem/lib/uaa/util.rb
  29. +0 −19 gem/lib/uaa/version.rb
  30. +0 −358 gem/spec/cli_spec.rb
  31. +0 −54 gem/spec/client_reg_spec.rb
  32. +0 −135 gem/spec/http_spec.rb
  33. +0 −168 gem/spec/integration_spec.rb
  34. +0 −48 gem/spec/misc_spec.rb
  35. +0 −49 gem/spec/spec_helper.rb
  36. +0 −365 gem/spec/stub_scim.rb
  37. +0 −487 gem/spec/stub_uaa.rb
  38. +0 −129 gem/spec/token_coder_spec.rb
  39. +0 −197 gem/spec/token_issuer_spec.rb
  40. +0 −280 gem/spec/user_account_spec.rb
View
16 gem/Gemfile
@@ -1,16 +0,0 @@
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#
-
-source "http://rubygems.org"
-
-# Specify your gem's dependencies in uaa.gemspec
-gemspec
View
56 gem/README.md
@@ -1,62 +1,8 @@
CloudFoundry UAA Gem
====================
-*NOTE: This gem is deprecated. Please use cf-uaa-lib and cf-uaac gems instead.
+*NOTE: This gem has been replaced. Please use cf-uaa-lib and cf-uaac gems.
They are available from rubygems.org or
https://github.com/cloudfoundry/cf-uaa-lib and
https://github.com/cloudfoundry/cf-uaac*
-Client gem for interacting with the CloudFoundry UAA server.
-
-Set up a local ruby environment (so sudo not required):
-
- $ rvm use 1.9.2
-
-or
-
- $ rbenv global 1.9.2-p180
-
-see: https://rvm.io/ or http://rbenv.org/
-
-Build the gem
-
- $ bundle install
- $ gem build cf-uaa-client.gemspec
-
-Install it
-
- $ gem install cf-uaa-client*.gem
-
-Run it
-
- $ uaac help
- $ uaac target uaa.cloudfoundry.com
- $ uaac token get <your-cf-username>
- $ uaac token decode
-
-Use the gem:
-
- #!/usr/bin/env ruby
- require 'uaa'
- token_issuer = CF::UAA::TokenIssuer.new("https://uaa.cloudfoundry.com", "vmc")
- puts token_issuer.prompts.inspect
- token = token_issuer.implicit_grant_with_creds(username: "<your_username>", password: "<your_password>")
- token_info = TokenCoder.decode(token.info[:access_token], nil, nil, false) #token signature not verified
- puts token_info[:user_name]
-
-## Tests
-
-Run the tests with rake:
-
- $ bundle exec rake test
-
-Run the tests and see a fancy coverage report:
-
- $ bundle exec rake cov
-
-Run integration tests (on a server running on localhost:8080/uaa):
-
- $ export UAA_CLIENT_ID="admin"
- $ export UAA_CLIENT_SECRET="adminsecret"
- $ export UAA_CLIENT_TARGET="http://localhost:8080/uaa"
- $ bundle exec rspec spec/integration_spec.rb
View
50 gem/Rakefile
@@ -1,50 +0,0 @@
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#
-
-require "rspec/core/rake_task"
-#require "bundler/gem_tasks" # only available in bundler >= 1.0.15
-#require "rdoc/task" # rdoc for current interfaces not written yet
-require "ci/reporter/rake/rspec"
-
-ENV['CI_REPORTS'] = File.expand_path("spec_reports")
-COV_REPORTS = File.expand_path("coverage")
-
-task :default => [:test]
-task :tests => [:test]
-task :spec => [:test]
-
-RSpec::Core::RakeTask.new("test") do |t|
- t.rspec_opts = ["--format", "documentation", "--colour"]
- t.pattern = "spec/**/*_spec.rb"
-end
-
-#RDoc::Task.new do |rd|
-# rd.rdoc_files.include("lib/**/*.rb")
-# rd.rdoc_dir = "doc"
-#end
-
-task :ci => [:pre_coverage, :rcov_reports, "ci:setup:rspec", :test]
-task :cov => [:pre_coverage, :test, :view_coverage]
-task :coverage => [:pre_coverage, :test]
-
-task :pre_coverage do
- rm_rf COV_REPORTS
- ENV['COVERAGE'] = "exclude-spec exclude-vendor"
-end
-
-task :rcov_reports do
- ENV['COVERAGE'] += " rcov"
-end
-
-task :view_coverage do
- `firefox #{File.join(COV_REPORTS, 'index.html')}`
-end
View
80 gem/bin/completion-helper
@@ -1,80 +0,0 @@
-#!/usr/bin/env ruby
-
-# given the indents, find sub-commands of a given command
-def find_sub_commands (lines, indents, i)
- result = Array.new
- x = i+1
- while x < lines.size && indents[x] > indents[i]
- if indents[x] - indents[i] == 1
- result.push(x)
- end
- x = x+1
- end
- result
-end
-
-def find_sub_command_index (lines, sub_command_indices, sub_command)
- sub_command_indices.each do |i|
- if lines[i] == sub_command
- return i
- end
- end
- -1
-end
-
-# traverse sub-command tree with the given list of args
-def traverse_command_tree(lines, sub_command_indices, args)
- #puts "traversing for #{args}"
- x = 0
- args.drop(1).each do |arg|
- next if arg.start_with? ("-")
- nx = find_sub_command_index(lines, sub_command_indices[x], arg)
- if nx != -1
- x = nx
- end
- end
- x
-end
-
-# use values in array1 as indices into array2 and find the subset from array2
-def find_subset(values, indices)
- result = Array.new
- indices.each do |i|
- result.push(values[i])
- end
- result.join(' ')
-end
-
-def get_cache_filename(cmd)
- curr_user = `whoami`.chomp
- home_dir = `echo ~#{curr_user}`.chomp
- "#{home_dir}/.#{cmd}-commands"
-end
-
-indent_char = "\t"
-command_file_name = get_cache_filename(ARGV[0])
-if !FileTest.exists?(command_file_name)
- `#{ARGV[0]} help commands > #{command_file_name}`
-end
-lines = File.readlines(command_file_name)
-children = Array.new
-indents = Array.new
-
-lines.each_with_index do |line, i|
- indents[i] = line.count(indent_char)
-end
-
-# now that we have computed the indent level for each line, remove new-lines and tabs
-lines.collect! { |line| line.gsub(/[#{indent_char}]/, '') }
-lines.collect! { |line| line.gsub(/[\n]/, '') }
-
-# pre-processing: find the sub-commands for command (using indent levels)
-lines.each_with_index do |line, i|
- children[i] = find_sub_commands(lines, indents, i)
-end
-
-# now that a sub-command tree is available, parse it using the input arguments to find the auto-completion options
-x = traverse_command_tree(lines, children, ARGV.drop(1))
-puts x == -1 ? "" : find_subset(lines, children[x])
-
-
View
5 gem/bin/uaac
@@ -1,5 +0,0 @@
-#!/usr/bin/env ruby
-
-$:.unshift File.expand_path File.join __FILE__, '..', '..', 'lib'
-require 'cli'
-exit CF::UAA::Cli.configure("#{ENV['HOME']}/.uaac.yml").run ? 0 : 1
View
34 gem/bin/uaac-completion.sh
@@ -1,34 +0,0 @@
-#! /bin/bash
-GLOBAL_OPTS="--help --no-help -h --version --no-version -v --debug --no-debug -d --trace --no-trace -t --config"
-
-_debug() {
- if [[ $UAAC_DEBUG -eq 1 ]] ; then
- echo "$@;"
- fi
-}
-
-_add_completion_options() {
- local current="${COMP_WORDS[${COMP_CWORD}]}"
- COMPREPLY=( "${COMPREPLY[@]}" $(compgen -W "$1" -- $current) )
-}
-
-_uaac() {
- local current="${COMP_WORDS[${COMP_CWORD}]}"
- local helper_input=()
- if [[ "$current" == "" ]] || [[ "$current" == " " ]] || [[ $current == -* ]] ; then
- helper_input=( ${COMP_WORDS[@]} )
- else
- helper_input=( ${COMP_WORDS[@]/$current/} )
- fi
-
- local parent_command="${COMP_WORDS[0]}"
- local uaac_opts=$(completion-helper "${parent_command}" "${helper_input[@]}")
- local opts=$uaac_opts
- if [[ $current == -* ]] ; then
- opts="${GLOBAL_OPTS} ${uaac_opts}"
- fi
- _add_completion_options "${opts}"
-
-}
-
-complete -F _uaac uaac
View
8 gem/bin/uaas
@@ -1,8 +0,0 @@
-#!/usr/bin/env ruby
-
-$:.unshift File.expand_path File.join __FILE__, '..', '..', 'lib'
-$:.unshift File.expand_path File.join __FILE__, '..', '..', 'spec'
-require 'stub_uaa'
-
-CF::UAA::Util.default_logger(:trace)
-CF::UAA::StubUAA.new.run('localhost', 8080)
View
48 gem/cf-uaa-client.gemspec
@@ -1,48 +0,0 @@
-# -*- encoding: utf-8 -*-
-#
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#
-
-$:.push File.expand_path("../lib", __FILE__)
-require "uaa/version"
-
-Gem::Specification.new do |s|
- s.name = "cf-uaa-client"
- s.version = CF::UAA::VERSION
- s.authors = ["Dave Syer", "Dale Olds", "Joel D'sa", "Vidya Valmikinathan", "Luke Taylor"]
- s.email = ["dsyer@vmware.com", "olds@vmware.com", "jdsa@vmware.com", "vidya@vmware.com", "ltaylor@vmware.com"]
- s.homepage = "https://github.com/cloudfoundry/uaa/tree/master/gem"
- s.summary = %q{Deprecated client and resource library for CloudFoundry UAA. Please use cf-uaa-lib and cf-uaac instead.}
- s.description = %q{Deprecated client library and command line tools for interacting with the CloudFoundry User Account and Authorization (UAA) server. The UAA is an OAuth2 Authorization Server so it can be used by webapps and command line apps to obtain access tokens to act on behalf of users. The tokens can then be used to access protected resources in a Resource Server. This library can be used by clients (as a convenient wrapper for mainstream oauth gems) or by resource servers.}
-
- s.rubyforge_project = "cf-uaa-client"
-
- s.files = `git ls-files`.split("\n")
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
- s.require_paths = ["lib"]
-
- # dependencies
- s.add_development_dependency "bundler"
- s.add_development_dependency "rake"
- s.add_development_dependency "rspec"
- s.add_development_dependency "simplecov"
- s.add_development_dependency "simplecov-rcov"
- s.add_development_dependency "ci_reporter"
- s.add_runtime_dependency "highline"
- s.add_runtime_dependency "rest-client"
- s.add_runtime_dependency "yajl-ruby"
- s.add_runtime_dependency "eventmachine"
- s.add_runtime_dependency "launchy"
- s.add_runtime_dependency "em-http-request", ">= 1.0.0.beta.3"
-
-end
View
14 gem/lib/cli.rb
@@ -1,14 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require "cli/runner"
View
274 gem/lib/cli/base.rb
@@ -1,274 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'highline'
-require 'optparse'
-
-module CF; module UAA end end
-
-module CF::UAA
-
-class Topic
-
- class << self; attr_reader :synonyms end
-
- def self.option_defs ; @option_defs || {} end
- def self.commands; @commands || {} end
- def self.topic(*args)
- return @description if args.empty?
- @synonyms = (args[0].split(' ') + args[1..-1]).map(&:downcase)
- @description = args[0]
- end
-
- def self.define_option(key, *args)
- @option_defs ||= {}
- raise "conflicting option definition for #{key}" if @option_defs.key?(key) && @option_defs[key] != args
- @option_defs[key] = args
- end
-
- def self.desc(template, desc, *options, &handler)
- parts, argc = template.split(' '), 0
- cmd = parts.each_with_object([]) { |p, o|
- if p =~ /^\[/
- argc = parts[-1] =~ /\.\.\.\]$/ ? -1 : parts.length - o.length
- break o
- end
- o << p
- }
- cmd_key = cmd.join('_').to_sym
- define_method(cmd_key, handler)
- @commands ||= {}
- @commands[cmd_key] = {parts: cmd, argc: argc, template: template, desc: desc, options: options}
- end
-
- def initialize(cli_class, options = {}, input = $stdin, output = $stdout)
- @cli_class, @options, @input, @output = cli_class, options, input, output
- @highline = HighLine.new(input, output)
- end
-
- def ask(prompt); @highline.ask("#{prompt}: ") end
- def ask_pwd(prompt); @highline.ask("#{prompt}: ") { |q| q.echo = '*' } end
- def say(msg); @output.puts(msg); msg end
- def gripe(msg); @output.puts(msg) end
- def opts; @options end
-
- def terminal_columns
- return @terminal_columns ||= 0 if @terminal_columns || !@output.tty?
- cols = HighLine::SystemExtensions.terminal_size.first rescue 0
- @terminal_columns = !cols || cols < 40 ? 0 : cols
- end
-
- def help_col_start
- return @help_col_start ||= 35 if @help_col_start || terminal_columns == 0 || terminal_columns > 80
- @help_col_start = terminal_columns / 2
- end
-
- def pp(obj, indent = 0, wrap = terminal_columns, label = nil)
- case obj
- when Array
- if obj.empty? || !obj[0].is_a?(Hash) && !obj[0].is_a?(Array)
- say_definition(indent, ("#{label}: " if label), Util.strlist(obj), nil, wrap)
- else
- say_definition(indent, "#{label}: ", nil, nil, wrap) if label
- obj.each {|o| pp o, indent, wrap, '-' }
- end
- when Hash
- say_definition(indent, label, nil, nil, wrap) if label
- obj.each {|k, v| pp v, indent + 2, wrap, k.to_s}
- when nil
- else say_definition(indent, ("#{label}: " if label), obj.to_s, nil, wrap)
- end
- obj
- end
-
- def say_definition(indent, term, text = nil, start = help_col_start, wrap = terminal_columns)
- cur = indent + (term ? term.length : 0)
- indent < 1 ? @output.printf("%s", term) : @output.printf("%*c%s", indent, ' ', term)
- if start.nil?
- start = 2 if (start = indent + 4) > wrap
- else
- start = 2 if start > wrap
- if cur < start
- @output.printf("%*c", start - cur, ' ')
- elsif cur > start
- @output.printf("\n%*c", start, ' ')
- end
- cur = start
- end
- return @output.printf("\n") unless text && !text.empty?
- text = text.dup
- text.each_line do |line|
- width = wrap == 0 ? 4096 : wrap - cur
- line = line.chomp
- while line.length > width
- i = line.rindex(' ', width) || width
- @output.printf("%s\n%*c", line[0..i - 1], start, ' ')
- width = wrap == 0 ? 4096 : wrap - start
- line = line[i..-1].strip
- end
- @output.printf("%s\n", line)
- cur = start
- end
- nil
- end
-
- def opt_help(key, args)
- raise "missing option definition for #{key}" unless args
- long = short = desc = nil
- args.each do |a|
- case a
- when /^-.$/ then short = a
- when /^--.*/ then long = a
- else desc = a
- end
- end
- raise "option definition must include long form (--#{key})" unless long
- [ short ? "#{short} | #{long}" : "#{long}", desc]
- end
-
- def opt_strs(opts)
- opts.each_with_object([]) { |o, a|
- @cli_class.option_defs[o].each { |d|
- case d
- when /^--\[no-\](\S+)/ then a << "--#{$1} --no-#{$1}"
- when /^--(\S+)/ then a << "--#{$1}"
- end
- }
- }.join(' ')
- end
-
- def say_cmd_helper(info, suffix = nil)
- say_definition 2, info[:template], info[:desc]
- info[:options].each do |o|
- odef, desc = opt_help(o, @cli_class.option_defs[o])
- say_definition help_col_start, "", desc ? "#{odef}, #{desc}" : odef
- end
- @output.print suffix
- end
-
- def say_command_help(args)
- say ""
- @cli_class.topics.each do |tpc|
- tpc.commands.each do |k, v|
- if args[0..v[:parts].length - 1] == v[:parts]
- say_cmd_helper(v, "\n")
- return "help command"
- end
- end
- end
- args = args.map(&:downcase)
- @cli_class.topics.each { |tpc| return say_help(tpc) unless (args & tpc.synonyms).empty? }
- gripe "No command or topic found to match: #{args.join(' ')}\n"
- end
-
- def say_help(topic = nil)
- @output.print "\n#{@cli_class.overview}\n" unless topic
- @cli_class.topics.each do |tpc|
- next if topic && topic != tpc
- @output.print "\n#{tpc.topic}\n"
- tpc.commands.each { |k, v| say_cmd_helper v }
- end
- if topic || !@cli_class.global_options
- @output.print("\n")
- return topic ? "help topic" : "help"
- end
- @output.print "\nGlobal options:\n"
- @cli_class.global_options.each do |o|
- odef, desc = opt_help(o, @cli_class.option_defs[o])
- say_definition 2, odef, desc
- end
- @output.print("\n")
- "help"
- end
-
- def add_command(branches, parts, opts = nil)
- if parts.empty?
- return if opts.nil? || opts.empty?
- return branches << {label: opt_strs(opts)}
- end
- if i = branches.find_index { |b| parts[0] == b[:label] }
- parts.shift
- else
- branches << {label: parts.shift, sub: []}
- i = -1
- end
- add_command(branches[i][:sub], parts, opts)
- end
-
- def print_tree(branches, indent)
- return unless branches
- branches.each do |b|
- indent.times { @output.print "\t" };
- @output.puts b[:label]
- print_tree b[:sub], indent + 1
- end
- end
-
- def say_commands
- tree = {label: File.basename($0), sub: []}
- @cli_class.topics.each {|t| t.commands.each {|k, v| add_command(tree[:sub], v[:parts].dup, v[:options])}}
- add_command(tree[:sub], [], @cli_class.global_options)
- @output.puts tree[:label]
- print_tree(tree[:sub], 1)
- "help commands"
- end
-
-end
-
-class BaseCli
-
- class << self
- attr_reader :input, :output, :option_defs
- attr_accessor :overview, :topics, :global_options
- end
-
- def self.preprocess_options(args, opts); end # to be implemented in subclass
- def self.too_many_args(cmd); end # to be implemented in subclass
-
- def self.run(args = ARGV)
- @input ||= $stdin
- @output ||= $stdout
- @option_defs = {}
- args = args.split if args.respond_to?(:split)
- @parser = OptionParser.new
- opts = @topics.each_with_object({}) do |tpc, o|
- tpc.option_defs.each do |k, optdef|
- @parser.on(*optdef) { |v| o[k] = v }
- @option_defs[k] = optdef
- end
- end
- @parser.parse! args
- preprocess_options(args, opts)
- @topics.each do |tpc|
- tpc.commands.each do |k, v|
- next unless args[0..v[:parts].length - 1] == v[:parts]
- args = args[v[:parts].length..-1]
- if v[:argc] == -1
- # variable args, leave args alone
- elsif args.length > v[:argc]
- too_many_args(v[:parts].dup)
- return nil
- elsif args.length < v[:argc]
- (v[:argc] - args.length).times { args << nil }
- end
- return tpc.new(self, opts, @input, @output).send(k, *args)
- end
- end
- @output.puts "#{File.basename($0)}: subcommand not found"
- rescue Exception => e
- @output.puts "#{File.basename($0)} error", "#{e.class}: #{e.message}", (e.backtrace if opts[:trace])
- end
-
-end
-
-end
View
104 gem/lib/cli/client_reg.rb
@@ -1,104 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/common'
-require 'uaa'
-
-module CF::UAA
-
-class ClientCli < CommonCli
-
- topic "Client Application Registrations", "reg"
-
- def client_reg_request
- (yield ClientReg.new(Config.target, auth_header)) || "success" # no exception means success
- rescue Exception => e
- complain e
- end
-
- def client_info(defaults, interact)
- del_op = "<delete>"
- info = {client_id: opts[:client_id]}
- info[:client_secret] = opts[:secret] if opts[:secret]
- CLIENT_SCHEMA.each_with_object(info) do |(k, p), info|
- v = nil
- if !opts.key?(k)
- info[k] = (v unless v == del_op) if interact ?
- !p.empty? && (v = askd("#{k.to_s.gsub('_', ' ')} (#{p})", defaults[k])) : (v = defaults[k])
- elsif opts[k] == del_op
- info[k] = nil
- else
- info[k] = v if (v = (opts[k].nil? || opts[k].empty? ? defaults[k]: opts[k]))
- end
- end
- end
-
- CLIENT_SCHEMA = { scope: "list", authorized_grant_types: "list", authorities: "list",
- access_token_validity: "seconds", refresh_token_validity: "seconds", redirect_uri: "list" }
-
- CLIENT_SCHEMA.each { |k, v| define_option(k, "--#{k} <#{v}>") }
-
- desc "clients", "List client registrations" do
- return unless reglist = client_reg_request { |cr| cr.list }
- pp reglist.each_with_object({}) { |(k, v), o| o[k] = ClientReg.multivalues_to_strings!(v) }
- end
-
- desc "client get [name]", "Get specific client registration" do |name|
- pp client_reg_request { |cr| ClientReg.multivalues_to_strings!(cr.get(clientname(name))) }
- end
-
- define_option :clone, "--clone <other_client>", "get default client settings from existing client"
- define_option :interact, "--[no-]interactive", "-i", "interactively verify all values"
-
- desc "client add [name]", "Add client registration",
- *CLIENT_SCHEMA.keys, :clone, :secret, :interact do |name|
- client_reg_request do |cr|
- opts[:client_id] = clientname(name)
- opts[:secret] = verified_pwd("New client secret", opts[:secret])
- defaults = opts[:clone] ? cr.get(opts[:clone]) : {}
- cr.create client_info(defaults, opts[:interact])
- end
- end
-
- desc "client update [name]", "Update client registration", *CLIENT_SCHEMA.keys, :interact do |name|
- client_reg_request do |cr|
- opts[:client_id] = clientname(name)
- defaults = opts[:interact] ? cr.get(opts[:client_id]) : {}
- info = client_info(defaults, opts[:interact])
- return cr.update info if info.length > 1
- say "No options given, nothing to update. Use -i for interactive update."
- end
- end
-
- desc "client delete [name]", "Delete client registration" do |name|
- client_reg_request { |cr| cr.delete(clientname(name)) }
- end
-
- desc "secret set [name]", "Set client secret", :secret do |name|
- client_reg_request do |cr|
- cr.change_secret(clientname(name), verified_pwd("New secret", opts[:secret]))
- end
- end
-
- define_option :old_secret, "-o", "--old_secret <secret>", "current secret"
- desc "secret change", "Change secret for authenticated client in current context", :old_secret, :secret do
- return say "context not set" unless client_id = Config.context.to_s
- client_reg_request do |cr|
- old = opts[:old_secret] || ask_pwd("Current secret")
- cr.change_secret(client_id, verified_pwd("New secret", opts[:secret]), old)
- end
- end
-
-end
-
-end
View
180 gem/lib/cli/common.rb
@@ -1,180 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/base'
-require 'cli/config'
-
-module CF::UAA
-
-class CommonCli < Topic
-
- def trace?; opts[:trace] end
- def debug?; opts[:debug] end
-
- def auth_header
- unless (ttype = Config.value(:token_type)) && (token = Config.value(:access_token))
- raise "Need an access token to complete this command. Please login."
- end
- "#{ttype} #{token}"
- end
-
- def username(name); name || ask("User name") end
- def userpwd(pwd = opts[:password]); pwd || ask_pwd("Password") end
- def clientname(name = opts[:client]); name || ask("Client name") end
- def clientsecret(name = opts[:secret]); name || ask_pwd("Client secret") end
-
- def verified_pwd(prompt, pwd = nil)
- while pwd.nil?
- pwd_a = ask_pwd prompt
- pwd_b = ask_pwd "Verify #{prompt.downcase}"
- pwd = pwd_a if pwd_a == pwd_b
- end
- pwd
- end
-
- def askd(prompt, defary)
- return ask(prompt) unless defary
- result = ask("#{prompt} [#{Util.strlist(defary)}]")
- result.nil? || result.empty? ? defary : result
- end
-
- def complain(e)
- case e
- when TargetError then gripe "\n#{e.message}:\n#{JSON.pretty_generate(e.info)}"
- when Exception
- gripe "\n#{e.class}: #{e.message}\n\n"
- gripe e.backtrace if trace?
- when String then gripe e
- else gripe "unknown type of gripe: #{e.class}, #{e}"
- end
- end
-
- def handle_request
- yield
- rescue Exception => e
- complain e
- end
-
- def update_target_info(info = nil)
- return if !info && Config.target_value(:prompts)
- info ||= Misc.server(Config.target)
- Config.target_opts(prompts: info[:prompts])
- Config.target_opts(token_endpoint: info[:token_endpoint]) if info[:token_endpoint]
- info
- end
-
-end
-
-class MiscCli < CommonCli
-
- topic "Miscellaneous", "misc"
-
- desc "version", "Display version" do
- say "UAA client #{VERSION}"
- end
-
- define_option :trace, "--[no-]trace", "-t", "display extra verbose debug information"
- define_option :debug, "--[no-]debug", "-d", "display debug information"
- define_option :help, "--[no-]help", "-h", "display helpful information"
- define_option :version, "--[no-]version", "-v", "show version"
- define_option :config, "--config [string|file]", "file to get/save configuration information or yaml string"
-
- desc "help [topic|command...]", "Display summary or details of command or topic" do |*args|
- # handle hidden command, output commands in form for bash completion
- return say_commands if args.length == 1 && args[0] == "commands"
- args.empty? ? say_help : say_command_help(args)
- end
-
- def normalize_url(url, scheme = nil)
- url = url.strip.gsub(/\/*$/, "")
- raise ArgumentError, "invalid whitespace in target url" if url =~ /\s/
- unless url =~ /^https?:\/\//
- return unless scheme
- url = "#{scheme}://#{url}"
- end
- url = URI.parse(url)
- url.host.downcase!
- url.to_s.to_sym
- end
-
- def bad_uaa_url(url, info)
- info.replace(Misc.server(url.to_s))
- nil
- rescue Exception => e
- "failed to access #{url}: #{e.message}"
- end
-
- define_option :force, "--[no-]force", "-f", "set even if target does not respond"
- desc "target [uaa_url]", "Display current or set new target", :force do |uaa_url|
- msg, info = nil, {}
- if uaa_url
- if uaa_url.to_i.to_s == uaa_url
- return gripe "invalid target index" unless url = Config.target?(uaa_url.to_i)
- elsif url = normalize_url(uaa_url)
- return gripe msg if (msg = bad_uaa_url(url, info)) unless opts[:force] || Config.target?(url)
- elsif !Config.target?(url = normalize_url(uaa_url, "https")) &&
- !Config.target?(url = normalize_url(uaa_url, "http"))
- if opts[:force]
- url = normalize_url(uaa_url, "https")
- elsif bad_uaa_url((url = normalize_url(uaa_url, "https")), info)
- return gripe msg if msg = bad_uaa_url((url = normalize_url(uaa_url, "http")), info)
- end
- end
- Config.target = url # we now have a canonical url set to https if possible
- update_target_info(info) if info[:prompts]
- end
- return say "no target set" unless Config.target
- return say "target set to #{Config.target}" unless Config.context
- say "target set to #{Config.target}, with context #{Config.context}"
- end
-
- desc "targets", "Display all targets" do
- cfg = Config.config
- return say "\nno targets\n" if cfg.empty?
- cfg.each_with_index { |(k, v), i| pp "#{i} #{v[:current] ? '*' : ' '} #{k}" }
- say "\n"
- end
-
- def config_pp(tgt = nil, ctx = nil)
- Config.config.each_with_index do |(k, v), i|
- next if tgt && tgt != k
- say ""
- splat = v[:current] ? '*' : ' '
- pp "[#{i}]#{splat}[#{k}]"
- v.each {|tk, tv| pp(tv, 2, terminal_columns, tk) unless [:contexts, :current, :prompts].include?(tk)}
- next unless v[:contexts]
- v[:contexts].each_with_index do |(sk, sv), si|
- next if ctx && ctx != sk
- say ""
- splat = sv[:current] && v[:current]? '*' : ' '
- sv.delete(:current)
- pp "[#{si}]#{splat}[#{sk}]", 2
- pp sv, 4
- end
- end
- say ""
- end
-
- desc "context [name]", "Display or set current context" do |ctx|
- ctx = ctx.to_i if ctx.to_i.to_s == ctx
- Config.context = ctx if ctx && Config.valid_context(ctx)
- (opts[:trace] ? Config.add_opts(trace: true) : Config.delete_attr(:trace)) if opts.key?(:trace)
- return say "no context set in target #{Config.target}" unless Config.context
- config_pp Config.target, Config.context
- end
-
- desc "contexts", "Display all contexts" do config_pp end
-
-end
-
-end
View
163 gem/lib/cli/config.rb
@@ -1,163 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'yaml'
-require 'uaa/util'
-
-module CF::UAA
-
-class Config
-
- class << self; attr_reader :target, :context end
-
- def self.config; @config ? @config.dup : {} end
- def self.loaded?; !!@config end
- def self.yaml; YAML.dump(Util.hash_keys(@config, :tostr)) end
- def self.target?(tgt) tgt if @config[tgt = subhash_key(@config, tgt)] end
-
- # if a yaml string is provided, config is loaded from the string, otherwise
- # config is assumed to be a file name to read and store config.
- # config can be retrieved in yaml form from Config.yaml
- def self.load(config = nil)
- @config = {}
- return unless config
- if config =~ /^---/ || config == ""
- @config = config == "" ? {} : YAML.load(config)
- @config_file = nil
- elsif File.exists?(@config_file = config)
- if (@config = YAML.load_file(@config_file)) && @config.is_a?(Hash)
- @config.each { |k, v| break @config = nil if k.to_s =~ / / }
- end
- unless @config && @config.is_a?(Hash)
- STDERR.puts "", "Invalid config file #{@config_file}.",
- "If it's from an old version of uaac, please remove it.",
- "Note that the uaac command structure has changed.",
- "Please review the new commands with 'uaac help'", ""
- exit 1
- end
- else # file doesn't exist, make sure we can write it now
- File.open(@config_file, 'w') { |f| f.write("--- {}\n\n") }
- end
- @config = Util.hash_keys(@config, :tosym)
- @context = current_subhash(@config[@target][:contexts]) if @target = current_subhash(@config)
- end
-
- def self.save
- File.open(@config_file, 'w') { |f| YAML.dump(Util.hash_keys(@config, :tostr), f) } if @config_file
- true
- end
-
- def self.target=(tgt)
- unless t = set_current_subhash(@config, tgt, @target)
- raise ArgumentError, "invalid target, #{tgt}"
- end
- @context = current_subhash(@config[t][:contexts])
- save
- @target = t
- end
-
- def self.target_opts(hash)
- raise ArgumentError, "target not set" unless @target
- return unless hash and !hash.empty?
- raise ArgumentError, "'contexts' is a reserved key" if hash.key?(:contexts)
- @config[@target].merge! hash
- save
- end
-
- def self.target_value(attr)
- raise ArgumentError, "target not set" unless @target
- @config[@target][attr]
- end
-
- def self.context=(ctx)
- raise ArgumentError, "target not set" unless @target
- unless c = set_current_subhash(@config[@target][:contexts] ||= {}, ctx, @context)
- raise ArgumentError, "invalid context, #{ctx}"
- end
- save
- @context = c
- end
-
- def self.valid_context(ctx)
- raise ArgumentError, "target not set" unless @target
- k = existing_key(@config[@target][:contexts] ||= {}, ctx)
- raise ArgumentError, "unknown context #{ctx}" unless k
- k
- end
-
- def self.delete(tgt = nil, ctx = nil)
- if tgt && ctx
- @config[tgt][:contexts].delete(ctx = valid_context(ctx))
- @context = nil if tgt == @target && ctx == @context
- elsif tgt
- @config.delete(tgt)
- @target = @context = nil if tgt == @target
- else
- @target, @context, @config = nil, nil, {}
- end
- save
- end
-
- def self.add_opts(hash)
- raise ArgumentError, "target and context not set" unless @target && @context
- return unless hash and !hash.empty?
- @config[@target][:contexts][@context].merge! hash
- save
- end
-
- def self.value(attr)
- raise ArgumentError, "target and context not set" unless @target && @context
- @config[@target][:contexts][@context][attr]
- end
-
- def self.delete_attr(attr)
- raise ArgumentError, "target and context not set" unless @target && @context
- @config[@target][:contexts][@context].delete(attr)
- end
-
- # these are all class methods and so can't really be private, but the
- # methods below here are not intended to be part of the public interface
- private
-
- def self.current_subhash(hash)
- return unless hash
- key = nil
- hash.each { |k, v| key ? v.delete(:current) : (key = k if v[:current]) }
- key
- end
-
- # key can be an integer index of the desired subhash or the key symbol or string
- def self.subhash_key(hash, key)
- case key
- when Integer then hash.each_with_index { |(k, v), i| return k if i == key }; nil
- when String then key.downcase.to_sym
- when Symbol then key.to_s.downcase.to_sym
- else nil
- end
- end
-
- def self.existing_key(hash, key)
- k = subhash_key(hash, key)
- k if hash[k]
- end
-
- def self.set_current_subhash(hash, newcurrent, oldcurrent)
- return unless k = subhash_key(hash, newcurrent)
- hash[oldcurrent].delete(:current) if oldcurrent
- (hash[k] ||= {}).merge!(current: true)
- k
- end
-
-end
-
-end
View
BIN  gem/lib/cli/favicon.ico
Binary file not shown
View
88 gem/lib/cli/group.rb
@@ -1,88 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'set'
-require 'cli/common'
-require 'uaa'
-
-module CF::UAA
-
-class GroupCli < CommonCli
-
- topic "Groups", "group"
-
- def acct_request
- (yield UserAccount.new(Config.target, auth_header)) || "success"
- rescue Exception => e
- complain e
- end
-
- def gname(name) name || ask("Group name") end
-
- desc "groups [filter]", "List groups", :attrs, :start, :count do |filter|
- pp acct_request { |ua|
- query = { attributes: opts[:attrs], filter: filter }
- if opts[:start] || opts[:count]
- ua.query_groups(query.merge!(startIndex: opts[:start], count: opts[:count]))
- else
- ua.all_pages(:query_groups, query)
- end
- }
- end
-
- desc "group get [name]", "Get specific group information" do |name|
- pp acct_request { |ua| ua.get_group_by_name(gname(name)) }
- end
-
- desc "group add [name]", "Adds a group" do |name|
- pp acct_request { |ua| ua.add_group(displayName: gname(name)) }
- end
-
- desc "group delete [name]", "Delete group" do |name|
- pp acct_request { |ua| ua.delete_group(ua.group_id_from_name(gname(name))) }
- end
-
- def id_set(objs)
- objs.each_with_object(Set.new) {|o, s|
- s << (o.is_a?(String)? o: (o[:id] || o[:value] || o[:memberId]))
- }
- end
-
- desc "member add [name] [members...]", "add members to a group" do |name, *members|
- pp acct_request { |ua|
- group = ua.get_group_by_name(gname(name))
- old_ids = id_set(group[:members] || [])
- new_ids = id_set(ua.ids(*members))
- raise "not all members found, none added" unless new_ids.size == members.size
- group[:members] = (old_ids + new_ids).to_a
- raise "no new members given" unless group[:members].size > old_ids.size
- ua.update_group(group[:id], group)
- }
- end
-
- desc "member delete [name] [members...]", "remove members from a group" do |name, *members|
- pp acct_request { |ua|
- group = ua.get_group_by_name(gname(name))
- old_ids = id_set(group[:members] || [])
- new_ids = id_set(ua.ids(*members))
- raise "not all members found, none deleted" unless new_ids.size == members.size
- group[:members] = (old_ids - new_ids).to_a
- raise "no existing members to delete" unless group[:members].size < old_ids.size
- #group.delete(:members) if group[:members].empty?
- ua.update_group(group[:id], group)
- }
- end
-
-end
-
-end
View
54 gem/lib/cli/info.rb
@@ -1,54 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/common'
-require 'uaa'
-
-module CF::UAA
-
-class InfoCli < CommonCli
-
- topic "System Information", "sys", "info"
-
- def misc_request(&blk) Config.target ? handle_request(&blk) : gripe("target not set") end
-
- desc "info", "get information about current target" do
- pp misc_request { update_target_info(Misc.server(Config.target)) }
- end
-
- desc "me", "get authenticated user information" do
- pp misc_request { Misc.whoami Config.target, auth_header }
- end
-
- desc "prompts", "Show prompts for credentials required for implicit grant post" do
- pp misc_request { update_target_info(Misc.server(Config.target))[:prompts] }
- end
-
- desc "signing key", "get the UAA's token signing key(s)", :client, :secret do
- info = misc_request { Misc.validation_key(Config.target,
- (clientname if opts.key?(:client)), (clientsecret if opts.key?(:client))) }
- Config.target_opts(signing_alg: info[:alg], signing_key: info[:value])
- pp info
- end
-
- desc "stats", "Show UAA's current usage statistics", :client, :secret do
- pp misc_request { Misc.varz(Config.target, clientname, clientsecret) }
- end
-
- desc "password strength [password]", "calculate strength score of a password" do |pwd|
- pp misc_request { Misc.password_strength(Config.target, userpwd(pwd)) }
- end
-
-end
-
-end
View
49 gem/lib/cli/runner.rb
@@ -1,49 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/token'
-require 'cli/user'
-require 'cli/group'
-require 'cli/info'
-require 'cli/client_reg'
-
-module CF::UAA
-
-class Cli < BaseCli
- @overview = "UAA Command Line Interface"
- @topics = [MiscCli, InfoCli, TokenCli, UserCli, GroupCli, ClientCli]
- @global_options = [:help, :version, :debug, :trace, :config]
-
- def self.configure(config_file = "", input = $stdin, output = $stdout)
- @config_file, @input, @output = config_file, input, output
- self
- end
-
- def self.too_many_args(cmd)
- @output.puts "\nToo many command line parameters given."
- run cmd.unshift("help")
- end
-
- def self.preprocess_options(args, opts)
- return args.replace(["version"]) if opts[:version]
- return args.unshift("help") if args.empty? || opts[:help] && args[0] != "version"
- Config.load(opts[:config] || @config_file) if opts.key?(:config) || !Config.loaded?
- [:trace, :debug].each do |k|
- opts[k] = true if !opts.key?(k) && Config.target && Config.context && Config.value(k)
- end
- Misc.logger = Util.default_logger(opts[:trace]? :trace: opts[:debug]? :debug: :warn, @output)
- end
-
-end
-
-end
View
294 gem/lib/cli/stub_server.rb
@@ -1,294 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'eventmachine'
-require 'date'
-require 'logger'
-require 'pp'
-require 'erb'
-
-module Stub
-
-#------------------------------------------------------------------------------
-class Request
- attr_reader :headers, :body, :path, :method
- def initialize; @state = :init end
-
- # adds data to the request, returns true if request is complete
- def complete?(str)
- if @state == :complete
- # byteslice is available in ruby 1.9.3
- str = @content_length >= body.bytesize ? str : body.respond_to?(:byteslice) ?
- body.byteslice(@content_length, body.bytesize - @content_length) + str :
- body[@content_length..-1] + str
- end
- add_lines str
- if @state == :body
- @content_length = headers[:content_length].to_i ||= 0
- @state = :complete unless body.bytesize < @content_length
- end
- @state == :complete
- end
-
- def cookies
- return {} unless chdr = @headers[:cookie]
- chdr.strip.split(/\s*;\s*/).each_with_object({}) do |pair, o|
- k, v = pair.split(/\s*=\s*/)
- o[k.downcase.gsub('-', '_').to_sym] = v
- end
- end
-
- private
-
- def add_lines(str)
- str.each_line do |ln|
- if @state == :complete || @state == :init
- start = ln.chomp!.split(/\s+/)
- @method, @path, @headers, @body = start[0].downcase.to_sym, start[1], {}, ""
- @state = :headers
- elsif @state == :body
- # TODO: figure out how to byteslice from ln to eos, append to @body, return
- @body << ln
- elsif (ln = ln.chomp).empty?
- @state = :body
- else
- key, sep, val = ln.partition(/:\s+/)
- @headers[key.downcase.gsub('-', '_').to_sym] = val
- end
- end
- end
-
-end
-
-#------------------------------------------------------------------------------
-class Reply
- attr_accessor :status, :headers, :body
- def initialize(status = 200) @status, @headers, @cookies, @body = status, {}, [], "" end
- def to_s
- reply = "HTTP/1.1 #{@status} OK\r\n"
- headers[:server] = "stub server"
- headers[:date] = DateTime.now.httpdate
- headers[:content_length] = body.bytesize
- headers.each { |k, v| reply << "#{k.to_s.gsub('_', '-')}: #{v}\r\n" }
- @cookies.each { |c| reply << "Set-Cookie: #{c}\r\n" }
- reply << "\r\n" << body
- end
- def json(status = nil, info)
- info = {message: info} unless info.respond_to? :each
- @status = status if status
- headers[:content_type] = "application/json"
- @body = info.to_json
- nil
- end
- def text(status = nil, info)
- @status = status if status
- headers[:content_type] = "text/plain"
- @body = info.pretty_inspect
- nil
- end
- def html(status = nil, info)
- @status = status if status
- headers[:content_type] = "text/html"
- info = ERB::Util.html_escape(info.pretty_inspect) unless info.is_a?(String)
- @body = "<html><body>#{info}</body></html>"
- nil
- end
- def set_cookie(name, value, options = {})
- @cookies << options.each_with_object("#{name}=#{value}") { |(k, v), o|
- o << (v.nil? ? "; #{k.to_s.gsub('_', '-')}" : "; #{k.to_s.gsub('_', '-')}=#{v}")
- }
- end
-end
-
-#------------------------------------------------------------------------------
-# request handler logic -- server is initialized with a class derived from this.
-# there will be one instance of this object per connection.
-class Base
- attr_accessor :request, :reply, :match, :server
-
- def self.route(http_methods, matcher, filters = {}, &handler)
- fail unless !EM.reactor_running? || EM.reactor_thread?
- matcher = Regexp.new("^#{Regexp.escape(matcher.to_s)}$") unless matcher.is_a?(Regexp)
- filters = filters.each_with_object({}) { |(k, v), o|
- o[k] = v.is_a?(Regexp) ? v : Regexp.new("^#{Regexp.escape(v.to_s)}$")
- }
- @routes ||= {}
- @route_number = (@route_number || 0) + 1
- route_name = "route_#{@route_number}".to_sym
- define_method(route_name, handler)
- [*http_methods].each do |m|
- m = m.to_sym
- @routes[m] ||= []
- i = @routes[m].index { |r| r[0].to_s.length < matcher.to_s.length }
- @routes[m].insert(i || -1, [matcher, filters, route_name]) unless i && @routes[m][i][0] == matcher
- end
- end
-
- def self.find_route(request)
- fail unless EM.reactor_thread?
- if @routes && (rary = @routes[request.method])
- rary.each { |r; m|
- next unless (m = r[0].match(request.path))
- r[1].each { |k, v|
- next if v.match(request.headers[k])
- return reply_in_kind(400, "header '#{k}: #{request.headers[k]}' is not accepted")
- }
- return [m, r[2]]
- }
- end
- [nil, :default_route]
- end
-
- def initialize(server)
- @server, @request, @reply, @match = server, Request.new, Reply.new, nil
- end
-
- def process
- @reply = Reply.new
- @match, handler = self.class.find_route(request)
- server.logger.debug "processing request to path #{request.path} for route #{@match ? @match.regexp : 'default'}"
- send handler
- reply.headers[:connection] ||= request.headers[:connection] if request.headers[:connection]
- server.logger.debug "replying to path #{request.path} with #{reply.body.length} bytes of #{reply.headers[:content_type]}"
- rescue Exception => e
- server.logger.debug "exception from route handler: #{e.message}"
- server.trace { e.backtrace }
- reply_in_kind 500, e
- end
-
- def reply_in_kind(status = nil, info)
- case request.headers[:accept]
- when /application\/json/ then reply.json(status, info)
- when /text\/html/ then reply.html(status, info)
- else reply.text(status, info)
- end
- end
-
- def default_route
- reply_in_kind(404, error: "path not handled")
- end
-
-end
-
-#------------------------------------------------------------------------------
-module Connection
- attr_accessor :req_handler
- def unbind; req_handler.server.delete_connection(self) end
-
- def receive_data(data)
- #req_handler.server.logger.debug "got #{data.bytesize} bytes: #{data.inspect}"
- return unless req_handler.request.complete? data
- req_handler.process
- send_data req_handler.reply.to_s
- if req_handler.reply.headers[:connection] =~ /^close$/i || req_handler.server.status != :running
- close_connection_after_writing
- end
- rescue Exception => e
- req_handler.server.logger.debug "exception from receive_data: #{e.message}"
- req_handler.server.trace { e.backtrace }
- close_connection
- end
-end
-
-#--------------------------------------------------------------------------
-class Server
- attr_reader :host, :port, :status, :logger
- attr_accessor :info
- def url; "http://#{@host}:#{@port}" end
- def trace(msg = nil, &blk); logger.trace(msg, &blk) if logger.respond_to?(:trace) end
-
- def initialize(req_handler, logger = Logger.new($stdout), info = nil)
- @req_handler, @logger, @info = req_handler, logger, info
- @connections, @status, @sig, @em_thread = [], :stopped, nil, nil
- end
-
- def start(hostname = "localhost", port = nil)
- raise ArgumentError, "attempt to start a server that's already running" unless @status == :stopped
- @host = hostname
- logger.debug "starting #{self.class} server #{@host}"
- EM.schedule do
- @sig = EM.start_server(@host, port || 0, Connection) { |c| initialize_connection(c) }
- @port = Socket.unpack_sockaddr_in(EM.get_sockname(@sig))[0]
- logger.debug "#{self.class} server started at #{url}, signature #{@sig}"
- end
- @status = :running
- self
- end
-
- def run_on_thread(hostname = "localhost", port = 0)
- raise ArgumentError, "can't run on thread, EventMachine already running" if EM.reactor_running?
- logger.debug { "starting eventmachine on thread" }
- cthred = Thread.current
- @em_thread = Thread.new do
- begin
- EM.run { start(hostname, port); cthred.run }
- logger.debug "server thread done"
- rescue Exception => e
- logger.debug { "unhandled exception on stub server thread: #{e.message}" }
- trace { e.backtrace }
- raise
- end
- end
- Thread.stop
- logger.debug "running on thread"
- self
- end
-
- def run(hostname = "localhost", port = 0)
- raise ArgumentError, "can't run, EventMachine already running" if EM.reactor_running?
- @em_thread = Thread.current
- EM.run { start(hostname, port) }
- logger.debug "server and event machine done"
- end
-
- # if on reactor thread, start shutting down but return if connections still
- # in process, and let them disconnect when complete -- server is not really
- # done until it's status is stopped.
- # if not on reactor thread, wait until everything's cleaned up and stopped
- def stop
- logger.debug "stopping server"
- @status = :stopping
- EM.stop_server @sig
- done if @connections.empty?
- sleep 0.1 while @status != :stopped unless EM.reactor_thread?
- end
-
- def delete_connection(conn)
- logger.debug "deleting connection"
- fail unless EM.reactor_thread?
- @connections.delete(conn)
- done if @status != :running && @connections.empty?
- end
-
- private
-
- def done
- fail unless @connections.empty?
- EM.stop if @em_thread && EM.reactor_running?
- @connections, @status, @sig, @em_thread = [], :stopped, nil, nil
- sleep 0.1 unless EM.reactor_thread? # give EM a chance to stop
- logger.debug EM.reactor_running? ?
- "server done but EM still running" : "server really done"
- end
-
- def initialize_connection(conn)
- logger.debug "starting connection"
- fail unless EM.reactor_thread?
- @connections << conn
- conn.req_handler = @req_handler.new(self)
- conn.comm_inactivity_timeout = 30
- end
-
-end
-
-end
View
217 gem/lib/cli/token.rb
@@ -1,217 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/common'
-require 'launchy'
-require 'uaa'
-require 'cli/stub_server'
-
-module CF::UAA
-
-class TokenCatcher < Stub::Base
-
- def process_grant(data)
- server.logger.debug "processing grant for path #{request.path}"
- secret = server.info.delete(:client_secret)
- ti = TokenIssuer.new(Config.target, server.info.delete(:client_id), secret,
- Config.target_value(:token_target))
- tkn = secret ? ti.authcode_grant(server.info.delete(:uri), data) :
- ti.implicit_grant(server.info.delete(:uri), data)
- server.info.update(tkn.info)
- reply.text "you are now logged in and can close this window"
- rescue TargetError => e
- reply.text "#{e.message}:\r\n#{JSON.pretty_generate(e.info)}\r\n#{e.backtrace}"
- rescue Exception => e
- reply.text "#{e.message}\r\n#{e.backtrace}"
- ensure
- server.logger.debug "reply: #{reply.body}"
- end
-
- route :get, '/favicon.ico' do
- reply.headers[:content_type] = "image/vnd.microsoft.icon"
- reply.body = File.read File.expand_path(File.join(__FILE__, '..', 'favicon.ico'))
- end
-
- route :get, %r{^/authcode\?(.*)$} do process_grant match[1] end
- route :post, '/callback' do process_grant request.body end
- route :get, '/callback' do
- server.logger.debug "caught redirect back from UAA after authentication"
- reply.headers[:content_type] = "text/html"
- reply.body = <<-HTML.gsub(/^ +/, '')
- <html><body><script type="text/javascript">
- var fragment = location.hash.substring(1);
- var req = new XMLHttpRequest();
- //document.write(fragment + "<br><br>");
- req.open('POST', "/callback", false);
- req.setRequestHeader("Content-type","application/x-www-form-urlencoded");
- req.send(fragment);
- document.write(req.responseText);
- </script></body></html>
- HTML
- end
-end
-
-class TokenCli < CommonCli
-
- topic "Tokens", "token", "login"
-
- def say_success(grant)
- say "\nSuccessfully fetched token via a #{grant} grant.\nTarget: #{Config.target}\nContext: #{Config.context}\n"
- end
-
- def issuer_request(client_id, secret = nil)
- update_target_info
- yield TokenIssuer.new(Config.target.to_s, client_id, secret, Config.target_value(:token_endpoint))
- rescue Exception => e
- complain e
- end
-
- define_option :client, "--client <name>", "-c"
- define_option :scope, "--scope <list>"
- desc "token get [credentials...]",
- "Gets a token by posting user credentials with an implicit grant request",
- :client, :scope do |*args|
- client_name = opts[:client] || "vmc"
- token = issuer_request(client_name, "") { |ti|
- prompts = ti.prompts
- creds = {}
- prompts.each do |k, v|
- if arg = args.shift
- creds[k] = arg
- elsif v[0] == "text"
- creds[k] = ask(v[1])
- elsif v[0] == "password"
- creds[k] = ask_pwd v[1]
- else
- raise "Unknown prompt type \"#{v[0]}\" received from #{Context.target}"
- end
- end
- ti.implicit_grant_with_creds(creds, opts[:scope]).info
- }
- return gripe "attempt to get token failed\n" unless token && token[:access_token]
- tokinfo = TokenCoder.decode(token[:access_token], nil, nil, false)
- Config.context = tokinfo[:user_name]
- Config.add_opts(user_id: tokinfo[:user_id])
- Config.add_opts token
- say_success "implicit (with posted credentials) "
- end
-
- define_option :secret, "--secret <secret>", "-s", "client secret"
- desc "token client get [name]",
- "Gets a token with client credentials grant", :secret, :scope do |id|
- id = clientname(id)
- return unless info = issuer_request(id, clientsecret) { |ti|
- ti.client_credentials_grant(opts[:scope]).info
- }
- Config.context = id
- Config.add_opts info
- say_success "client credentials"
- end
-
- define_option :password, "-p", "--password <password>", "user password"
- desc "token owner get [client] [user]", "Gets a token with a resource owner password grant",
- :secret, :password, :scope do |client, user|
- return unless info = issuer_request(clientname(client), clientsecret) { |ti|
- ti.owner_password_grant(user = username(user), userpwd, opts[:scope]).info
- }
- Config.context = user
- Config.add_opts info
- say_success "owner password"
- end
-
- desc "token refresh [refreshtoken]", "Gets a new access token from a refresh token", :client, :secret, :scope do |rtok|
- rtok ||= Config.value(:refresh_token)
- Config.add_opts issuer_request(clientname, clientsecret) { |ti| ti.refresh_token_grant(rtok, opts[:scope]).info }
- say_success "refresh"
- end
-
- VMC_TOKEN_FILE = File.join ENV["HOME"], ".vmc_token"
- VMC_TARGET_FILE = File.join ENV["HOME"], ".vmc_target"
-
- def use_browser(client_id, secret = nil)
- catcher = Stub::Server.new(TokenCatcher,
- Util.default_logger(debug? ? :debug : trace? ? :trace : :info),
- client_id: client_id, client_secret: secret).run_on_thread("localhost", opts[:port])
- uri = issuer_request(client_id, secret) { |ti|
- secret ? ti.authcode_uri("#{catcher.url}/authcode", opts[:scope]) :
- ti.implicit_uri("#{catcher.url}/callback", opts[:scope])
- }
- return unless catcher.info[:uri] = uri
- say "launching browser with #{uri}" if trace?
- Launchy.open(uri, debug: true, dry_run: false)
- print "waiting for token "
- while catcher.info[:uri] || !catcher.info[:access_token]
- sleep 5
- print "."
- end
- Config.context = TokenCoder.decode(catcher.info[:access_token], nil, nil, false)[:user_name]
- Config.add_opts catcher.info
- say_success secret ? "authorization code" : "implicit"
- return unless opts[:vmc]
- begin
- vmc_target = File.open(VMC_TARGET_FILE, 'r') { |f| f.read.strip }
- tok_json = File.open(VMC_TOKEN_FILE, 'r') { |f| f.read } if File.exists?(VMC_TOKEN_FILE)
- vmc_tokens = Util.json_parse(tok_json, :none) || {}
- vmc_tokens[vmc_target] = auth_header
- File.open(VMC_TOKEN_FILE, 'w') { |f| f.write(vmc_tokens.to_json) }
- rescue Exception => e
- gripe "\nUnable to save token to vmc token file"
- complain e
- end
- end
-
- define_option :port, "--port <number>", "pin internal server to specific port"
- define_option :vmc, "--[no-]vmc", "save token in the ~/.vmc_tokens file"
- desc "token authcode get", "Gets a token using the authcode flow with browser",
- :client, :secret, :scope, :vmc, :port do use_browser(clientname, clientsecret) end
-
- desc "token implicit get", "Gets a token using the implicit flow with browser",
- :client, :scope, :vmc, :port do use_browser opts[:client] || "vmc" end
-
- define_option :key, "--key <key>", "Token validation key"
- desc "token decode [token] [tokentype]", "Show token contents as parsed locally or by the UAA. " +
- "Decodes locally unless --client and --secret are given. Validates locally if --key given or server's signing key has been retrieved",
- :key, :client, :secret do |token, ttype|
- ttype = "bearer" if token && !ttype
- token ||= Config.value(:access_token)
- ttype ||= Config.value(:token_type)
- return say "no token to decode" unless token && ttype
- handle_request do
- if opts[:client] && opts[:secret]
- pp Misc.decode_token(Config.target, opts[:client], opts[:secret], token, ttype)
- else
- seckey = opts[:key] || (Config.target_value(:signing_key) if Config.target_value(:signing_alg) !~ /rsa$/i)
- pubkey = opts[:key] || (Config.target_value(:signing_key) if Config.target_value(:signing_alg) =~ /rsa$/i)
- info = TokenCoder.decode(token, seckey, pubkey, seckey || pubkey)
- say seckey || pubkey ? "\nValid token signature\n\n": "\nNote: no key given to validate token signature\n\n"
- pp info
- end
- end
- end
-
- define_option :all, "--[no-]all", "remove all contexts"
- desc "token delete [contexts...]",
- "Delete current or specified context tokens and settings", :all do |*args|
- begin
- return Config.delete if opts[:all]
- return args.each { |arg| Config.delete(Config.target, arg.to_i.to_s == arg ? arg.to_i : arg) } unless args.empty?
- return Config.delete(Config.target, Config.context) if Config.context
- say "no target set, no contexts given -- nothing to delete"
- rescue Exception => e
- complain e
- end
- end
-
-end
-
-end
View
120 gem/lib/cli/user.rb
@@ -1,120 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'cli/common'
-require 'uaa'
-
-module CF::UAA
-
-class UserCli < CommonCli
-
- topic "User Accounts", "account"
-
- define_option :givenName, "--given_name <name>"
- define_option :familyName, "--family_name <name>"
- define_option :emails, "--emails <addresses>"
- define_option :phoneNumbers, "--phones <phone_numbers>"
- USER_INFO_OPTS = [:givenName, :familyName, :emails, :phoneNumbers]
-
- def user_opts(info = {})
- [:emails, :phoneNumbers].each do |o|
- next unless opts[o]
- info[o] = Util.arglist(opts[o]).each_with_object([]) { |v, a| a << {:value => v} }
- end
- n = [:givenName, :familyName].each_with_object({}) { |o, n| n[o] = opts[o] if opts[o] }
- info[:name] = n unless n.empty?
- info
- end
-
- def acct_request
- yield UserAccount.new(Config.target, auth_header)
- rescue Exception => e
- complain e
- end
-
- define_option :attrs, "-a", "--attributes <names>", "output for each user"
- define_option :start, "--start <number>", "start of output page"
- define_option :count, "--count <number>", "max number per page"
- desc "users [filter]", "List user accounts", :attrs, :start, :count do |filter|
- pp acct_request { |ua|
- query = { attributes: opts[:attrs], filter: filter }
- if opts[:start] || opts[:count]
- ua.query_users(query.merge!(startIndex: opts[:start], count: opts[:count]))
- else
- ua.all_pages(:query_users, query)
- end
- }
- end
-
- desc "user get [name]", "Get specific user account" do |name|
- pp acct_request { |ua| ua.get_by_name(username(name)) }
- end
-
- desc "user add [name]", "Add a user account", *USER_INFO_OPTS, :password do |name|
- info = {userName: username(name), password: verified_pwd("Password", opts[:password])}
- pp acct_request { |ua| ua.add(user_opts(info)); "user account successfully added" }
- end
-
- define_option :del_attrs, "--del_attrs <attr_names>", "list of attributes to delete"
- desc "user update [name]", "Update a user account with specified options",
- *USER_INFO_OPTS, :del_attrs do |name|
- return say "no user updates specified" if (updates = user_opts).empty?
- pp acct_request { |ua|
- info = ua.get_by_name(username(name))
- opts[:del_attrs].each { |a| info.delete(a) } if opts[:del_attrs]
- ua.update(info[:id], info.merge(updates))
- "user account successfully updated"
- }
- end
-
- desc "user patch [name] [updates]", "Patch user account with updates in SCIM json format",
- :del_attrs do |name, updates|
- pp acct_request { |ua|
- ua.update(username(name), Util.json_parse(updates), opts[:del_attrs])
- "user account successfully updated"
- }
- end
-
- desc "user delete [name]", "Delete user account" do |name|
- pp acct_request { |ua|
- ua.delete_by_name(username(name))
- "user account successfully deleted"
- }
- end
-
- desc "user ids [username|id...]", "Gets user names and ids for the given users" do |*users|
- pp acct_request { |ua|
- users = Util.arglist(ask("names or ids of users")) if !users || users.empty?
- ua.ids_exclusive(*users)
- }
- end
-
- desc "password set [name]", "Set password", :password do |name|
- pp acct_request { |ua|
- ua.change_password_by_name(username(name), verified_pwd("New password", opts[:password]))
- "password successfully set"
- }
- end
-
- define_option :old_password, "-o", "--old_password <password>", "current password"
- desc "password change", "Change password for authenticated user in current context", :old_password, :password do
- pp acct_request { |ua|
- oldpwd = opts[:old_password] || ask_pwd("Current password")
- ua.change_password(Config.value(:user_id), verified_pwd("New password", opts[:password]), oldpwd)
- "password successfully changed"
- }
- end
-
-end
-
-end
View
19 gem/lib/uaa.rb
@@ -1,19 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require "uaa/version"
-require "uaa/misc"
-require "uaa/token_issuer"
-require "uaa/token_coder"
-require "uaa/user_account"
-require "uaa/client_reg"
View
77 gem/lib/uaa/client_reg.rb
@@ -1,77 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'uaa/http'
-
-module CF::UAA
-
-# This class is for apps that need to manage Client registrations within the UAA.
-class ClientReg
-
- include Http
-
- MULTI_VALUED = [:scope, :authorized_grant_types, :authorities, :redirect_uri]
-
- def self.multivalues_to_arrays!(info)
- MULTI_VALUED.each_with_object(info) { |v, o| o[v] = Util.arglist(o[v]) if o[v] }
- end
-
- def self.multivalues_to_strings!(info)
- MULTI_VALUED.each_with_object(info) { |v, o| o[v] = Util.strlist(o[v]) if o[v] }
- end
-
- # the auth_header parameter refers to a string that can be used in an
- # authorization header. For oauth with jwt tokens this would be something
- # like "bearer xxxx.xxxx.xxxx". The Token class returned by TokenIssuer
- # provides an auth_header method for this purpose.
- def initialize(target, auth_header)
- @target, @auth_header = target, auth_header
- end
-
- # takes a hash of fields currently supported by the uaa:
- # client_id (required),
- # client_secret,
- # scope (array of strings or space or comma separated fields),
- # authorized_grant_types (array of strings or space or comma separated fields),
- # authorities (array of strings or space or comma separated fields),
- # access_token_validity (integer)
- # refresh_token_validity (integer)
- # redirect_uri (array of strings or space or comma separated fields),
-
- def create(info)
- info = Util.hash_keys(info)
- raise ArgumentError, "a client registration must specify a unique client id" unless info[:client_id]
- info = self.class.multivalues_to_arrays! info
- json_parse_reply *json_post(@target, "/oauth/clients", info, @auth_header)
- end
-
- def update(info)
- info = Util.hash_keys(info)
- raise ArgumentError, "a client registration update must specify a unique client id" unless info[:client_id]
- info = self.class.multivalues_to_arrays! info
- json_parse_reply *json_put(@target, "/oauth/clients/#{URI.encode(info[:client_id])}", info, @auth_header)
- end
-
- def get(id) json_get @target, "/oauth/clients/#{URI.encode(id)}", @auth_header end
- def delete(id) http_delete @target, "/oauth/clients/#{URI.encode(id)}", @auth_header end
- def list; json_get @target, "/oauth/clients", @auth_header end
-
- def change_secret(client_id, new_secret, old_secret = nil)
- req = { secret: new_secret }
- req[:oldSecret] = old_secret if old_secret
- json_parse_reply(*json_put(@target, "/oauth/clients/#{URI.encode(client_id)}/secret", req, @auth_header))
- end
-
-end
-
-end
View
160 gem/lib/uaa/http.rb
@@ -1,160 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-require 'rest_client'
-require 'eventmachine'
-require 'em-http'
-require 'fiber'
-require 'base64'
-require 'uaa/util'
-
-module CF::UAA
-
-class BadTarget < RuntimeError; end
-class NotFound < RuntimeError; end
-class BadResponse < RuntimeError; end
-class InvalidToken < RuntimeError; end
-class HTTPException < RuntimeError; end
-class TargetError < RuntimeError
- attr_reader :info
- def initialize(error_info = {})
- @info = error_info
- end
-end
-
-# Utility accessors and methods for objects that want to access JSON web APIs.
-module Http
-
- attr_accessor :proxy, :async
- def logger=(logr); @logger = logr end
- def logger ; @logger ||= Util.default_logger end
- def trace? ; @logger && @logger.respond_to?(:trace?) && @logger.trace? end
-
- def self.basic_auth(name, password)
- "Basic " + Base64::strict_encode64("#{name}:#{password}")
- end
-
- # json helpers
-
- def add_auth_header(auth, headers) headers[:authorization] = auth if auth; headers end
-
- def json_get(target, path = nil, authorization = nil, headers = {})
- json_parse_reply(*http_get(target, path,
- add_auth_header(authorization, headers.merge(accept: "application/json"))))
- end
-
- def json_post(target, path, body, authorization, headers = {})
- http_post(target, path, body.to_json,
- add_auth_header(authorization, headers.merge(content_type: "application/json")))
- end
-
- def json_put(target, path, body, authorization = nil, headers = {})
- http_put(target, path, body.to_json,
- add_auth_header(authorization, headers.merge(content_type: "application/json")))
- end
-
- def json_patch(target, path, body, authorization = nil, headers = {})
- http_patch(target, path, body.to_json,
- add_auth_header(authorization, headers.merge(content_type: "application/json")))
- end
-
- def json_parse_reply(status, body, headers)
- unless [200, 201, 204, 400, 401, 403].include? status
- raise (status == 404 ? NotFound : BadResponse), "invalid status response: #{status}"
- end
- if body && !body.empty? && (headers && headers[:content_type] !~ /application\/json/i || status == 204)
- raise BadResponse, "received invalid response content or type"
- end
- parsed_reply = Util.json_parse(body)
- if status >= 400
- raise parsed_reply && parsed_reply[:error] == "invalid_token" ?
- InvalidToken : TargetError.new(parsed_reply), "error response"
- end
- parsed_reply
- rescue JSON::ParserError
- raise BadResponse, "invalid JSON response"
- end
-
- # HTTP helpers
-
- def http_get(target, path = nil, headers = {}) request(target, :get, path, nil, headers) end
- def http_post(target, path, body, headers = {}) request(target, :post, path, body, headers) end
- def http_put(target, path, body, headers = {}) request(target, :put, path, body, headers) end
- def http_patch(target, path, body, headers = {}) request(target, :patch, path, body, headers) end
-
- def http_delete(target, path, authorization)
- status = request(target, :delete, path, nil, authorization: authorization)[0]
- unless [200, 204].include?(status)
- raise (status == 404 ? NotFound : BadResponse), "invalid response from #{path}: #{status}"
- end
- end
-
- def request(target, method, path, payload = nil, headers = {})
- headers = headers.dup
- headers[:proxy_user] = @proxy if @proxy unless headers[:proxy_user]
- headers[:accept] = headers[:content_type] if headers[:content_type] && !headers[:accept]
-
- req = { method: method, url: "#{target}#{path}", payload: payload,
- headers: Util.hash_keys(headers, :todash) }
-
- logger.debug { "---> #{@async ? 'async' : ''}\nrequest: #{method} #{req[:url]}\n" +
- "headers: #{req[:headers]}\n#{'body: ' + Util.truncate(payload.to_s, trace? ? 50000 : 50) if payload}" }
-
- status, body, response_headers = async ? perform_ahttp_request(req) : perform_http_request(req)
-
- logger.debug { "<---\nresponse: #{status}\nheaders: #{response_headers}\n" +
- "#{'body: ' + Util.truncate(body.to_s, trace? ? 50000: 50) if body}" }
-
- [status, body, Util.hash_keys(response_headers, :undash)]
-
- rescue Exception => e
- e.message.replace "Target #{target}, #{e.message}"
- logger.debug { "<---- no response due to exception: #{e}" }
- raise e
- end
-
- private
-
- def perform_http_request(req)
- RestClient::Request.execute(req) { |resp, req| [resp.code, resp.body, resp.headers] }
- rescue URI::Error, SocketError, SystemCallError => e
- raise BadTarget, "error: #{e.message}"
- rescue RestClient::Exception, Net::HTTPBadResponse => e
- raise HTTPException, "HTTP exception: #{e.class}: #{e}"
- end
-
- def perform_ahttp_request(req)
- f = Fiber.current
- connection = EventMachine::HttpRequest.new(req[:url], connect_timeout: 10, inactivity_timeout: 10)
- client = connection.setup_request(req[:method].to_sym, head: req[:headers], body: req[:payload])
-
- # This check is for proper error handling with em-http-request 1.0.0.beta.3
- if defined?(EventMachine::FailedConnection) && connection.is_a?(EventMachine::FailedConnection)
- raise BadTarget, "HTTP connection setup error: #{client.error}"
- end
-
- client.callback { f.resume [client.response_header.http_status, client.response, client.response_header] }
- client.errback { f.resume [:error, client.error] }
- result = Fiber.yield
- if result[0] == :error
- raise BadTarget, "connection failed" unless result[1] && result[1] != ""
- raise BadTarget, "connection refused" if result[1].to_s =~ /ECONNREFUSED/
- raise BadTarget, "unable to resolve address" if /unable.*server.*address/.match result[1]
- raise HTTPException, result[1]
- end
- result
- end
-
-end
-
-end
View
104 gem/lib/uaa/misc.rb
@@ -1,104 +0,0 @@
-#--
-# Cloud Foundry 2012.02.03 Beta
-# Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
-#
-# This product is licensed to you under the Apache License, Version 2.0 (the "License").
-# You may not use this product except in compliance with the License.
-#
-# This product includes a number of subcomponents with
-# separate copyright notices and license terms. Your use of these
-# subcomponents is subject to the terms and conditions of the
-# subcomponent's license, as noted in the LICENSE file.
-#++
-
-# This class is for Web Client Apps (in the OAuth2 sense) that want
-# access to authenticated user information. Basically this class is
-# an OpenID Connect client.
-
-require 'uaa/http'