Skip to content

Commit

Permalink
Add UsernameToken support
Browse files Browse the repository at this point in the history
  • Loading branch information
Avin Mathew committed May 19, 2014
1 parent fe668e1 commit 08ef7d3
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 13 deletions.
1 change: 1 addition & 0 deletions isbm_adaptor.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'webmock', '~> 1.18.0'

s.add_runtime_dependency 'activesupport', '>= 1.0.0'
s.add_runtime_dependency 'akami', '>= 1.0.0'
s.add_runtime_dependency 'builder', '>= 2.1.2'
s.add_runtime_dependency 'nokogiri', '>= 1.4.0'
s.add_runtime_dependency 'savon', '>= 2.0.0'
Expand Down
74 changes: 65 additions & 9 deletions lib/isbm_adaptor/channel_management.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ChannelManagement < IsbmAdaptor::Client
# Creates a new ISBM ChannelManagement client.
#
# @param endpoint [String] the SOAP endpoint URI
# @option options [Array<String>] :wsse_auth username and password, i.e. [username, password]
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
# @option options [Boolean] :log (true) specify whether requests are logged
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
Expand All @@ -18,23 +19,61 @@ def initialize(endpoint, options = {})
# @param uri [String] the channel URI
# @param type [Symbol] the channel type, either publication or request (symbol or titleized string)
# @param description [String] the channel description, defaults to nil
# @param tokens [Hash] username password pairs, e.g. {'u1' => 'p1', 'u2' => 'p2'}
# @return [void]
# @raise [ArgumentError] if uri or type are blank or type is not a valid Symbol
def create_channel(uri, type, description = nil)
def create_channel(uri, type, description = nil, tokens = {})
validate_presence_of uri, 'Channel URI'
validate_presence_of type, 'Channel Type'
channel_type = type.to_s.downcase.capitalize
raise ArgumentError, "#{channel_type} is not a valid type. Must be either Publication or Request." unless IsbmAdaptor::Channel::TYPES.include?(channel_type)

message = { 'ChannelURI' => uri,
'ChannelType' => channel_type }
message['ChannelDescription'] = description unless description.nil?
message['ChannelDescription'] = description unless description.nil?
message['SecurityToken'] = security_token_hash(tokens) if tokens.any?

@client.call(:create_channel, message: message)

return true
end

# Adds security tokens to a channel.
#
# @param uri [String] the channel URI
# @param tokens [Hash] username password pairs, e.g. {'u1' => 'p1', 'u2' => 'p2'}
# @return [void]
# @raise [ArgumentError] if uri is blank or no tokens are provided
def add_security_tokens(uri, tokens = {})
validate_presence_of uri, 'Channel URI'
validate_presence_of tokens, 'Security Tokens'

message = { 'ChannelURI' => uri,
'SecurityToken' => security_token_hash(tokens) }

@client.call(:add_security_tokens, message: message)

return true
end

# Removes security tokens from a channel.
#
# @param uri [String] the channel URI
# @param tokens [Hash] username password pairs, e.g. {'u1' => 'p1', 'u2' => 'p2'}
# @return [void]
# @raise [ArgumentError] if uri is blank or no tokens are provided
def remove_security_tokens(uri, tokens = {})
validate_presence_of uri, 'Channel URI'
validate_presence_of tokens, 'Security Tokens'

message = { 'ChannelURI' => uri,
'SecurityToken' => security_token_hash(tokens) }

@client.call(:remove_security_tokens, message: message)

return true
end

# Deletes the specified channel.
#
# @param uri [String] the channel URI
Expand All @@ -48,31 +87,48 @@ def delete_channel(uri)
return true
end

# Gets information about the specified channel
# Gets information about the specified channel.
#
# @param uri [String] the channel URI
# @yield locals local options, including :wsse_auth
# @return [Channel] the queried channel
# @raise [ArgumentError] if uri is blank
def get_channel(uri)
def get_channel(uri, &block)
validate_presence_of uri, 'Channel URI'

response = @client.call(:get_channel, message: { 'ChannelURI' => uri })
response = @client.call(:get_channel, message: { 'ChannelURI' => uri }, &block)

hash = response.to_hash[:get_channel_response][:channel]
IsbmAdaptor::Channel.from_hash(hash)
end

# Gets information about all channels
# Gets information about all channels.
#
# @return [Array<Channel>] all channels on the ISBM
def get_channels
response = @client.call(:get_channels)
# @yield locals local options, including :wsse_auth
# @return [Array<Channel>] all authorized channels on the ISBM
def get_channels(&block)
response = @client.call(:get_channels, {}, &block)

channels = response.to_hash[:get_channels_response][:channel]
channels = [channels].compact unless channels.is_a?(Array)
channels.map do |hash|
IsbmAdaptor::Channel.from_hash(hash)
end
end

private
# Returns tokens mapped to wsse:UsernameToken hash.
def security_token_hash(tokens)
wsse = Akami.wsse
tokens.map do |username, password|
wsse.credentials(username, password)
# Extract the UsernameToken element
username_token = wsse.send(:wsse_username_token)['wsse:Security']
# Restore the wsse namespace
ns = {'xmlns:wsse' => Akami::WSSE::WSE_NAMESPACE}
username_token[:attributes!]['wsse:UsernameToken'].merge!(ns)
username_token
end
end
end
end
1 change: 1 addition & 0 deletions lib/isbm_adaptor/consumer_publication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ConsumerPublication < IsbmAdaptor::Client
# Creates a new ISBM ConsumerPublication client.
#
# @param endpoint [String] the SOAP endpoint URI
# @option options [Array<String>] :wsse_auth username and password, i.e. [username, password]
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
# @option options [Boolean] :log (true) specify whether requests are logged
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
Expand Down
1 change: 1 addition & 0 deletions lib/isbm_adaptor/consumer_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ConsumerRequest < IsbmAdaptor::Client
# Creates a new ISBM ConsumerRequest client.
#
# @param endpoint [String] the SOAP endpoint URI
# @option options [Array<String>] :wsse_auth username and password, i.e. [username, password]
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
# @option options [Boolean] :log (true) specify whether requests are logged
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
Expand Down
1 change: 1 addition & 0 deletions lib/isbm_adaptor/provider_publication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ProviderPublication < IsbmAdaptor::Client
# Creates a new ISBM ProviderPublication client.
#
# @param endpoint [String] the SOAP endpoint URI
# @option options [Array<String>] :wsse_auth username and password, i.e. [username, password]
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
# @option options [Boolean] :log (true) specify whether requests are logged
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
Expand Down
1 change: 1 addition & 0 deletions lib/isbm_adaptor/provider_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ProviderRequest < IsbmAdaptor::Client
# Creates a new ISBM ProviderRequest client.
#
# @param endpoint [String] the SOAP endpoint URI
# @option options [Array<String>] :wsse_auth username and password, i.e. [username, password]
# @option options [Object] :logger (Rails.logger or $stdout) location where log should be output
# @option options [Boolean] :log (true) specify whether requests are logged
# @option options [Boolean] :pretty_print_xml (false) specify whether request and response XML are formatted
Expand Down
44 changes: 40 additions & 4 deletions spec/lib/isbm_adaptor/channel_management_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
let(:uri) { 'Test' }
let(:type) { :publication }
let(:description) { 'description' }
let(:client) { IsbmAdaptor::ChannelManagement.new(ENDPOINTS['channel_management'], OPTIONS) }
let(:tokens) { {u1: :p1, u2: :p2} }
let(:client) do
options = OPTIONS.merge(wsse_auth: ['u1', 'p1'])
IsbmAdaptor::ChannelManagement.new(ENDPOINTS['channel_management'], options)
end

context 'when invalid arguments' do
describe '#create_channel' do
Expand All @@ -21,9 +25,23 @@
end
end

describe '#get_channel' do
describe '#add_security_tokens' do
it 'raises error with no URI' do
expect { client.get_channel(nil) }.to raise_error ArgumentError
expect { client.add_security_tokens(nil, tokens) }.to raise_error ArgumentError
end

it 'raises error with no tokens' do
expect { client.add_security_tokens(uri, nil) }.to raise_error ArgumentError
end
end

describe '#remove_security_tokens' do
it 'raises error with no URI' do
expect { client.remove_security_tokens(nil, tokens) }.to raise_error ArgumentError
end

it 'raises error with no tokens' do
expect { client.remove_security_tokens(uri, nil) }.to raise_error ArgumentError
end
end

Expand All @@ -32,10 +50,28 @@
expect { client.delete_channel(nil) }.to raise_error ArgumentError
end
end

describe '#get_channel' do
it 'raises error with no URI' do
expect { client.get_channel(nil) }.to raise_error ArgumentError
end
end
end

context 'when valid arguments' do
before { client.create_channel(uri, type, description) }
before { client.create_channel(uri, type, description, tokens) }

pending '#add_security_token' do
it 'does not raise error' do
expect { client.add_security_tokens(uri, tokens) }.not_to raise_error
end
end

pending '#remove_security_token' do
it 'does not raise error' do
expect { client.remove_security_token(uri, tokens) }.not_to raise_error
end
end

describe '#get_channel' do
let(:channel) { client.get_channel(uri) }
Expand Down

0 comments on commit 08ef7d3

Please sign in to comment.