pepper 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
File without changes
@@ -0,0 +1,61 @@
1
+ module Pepper
2
+ module Commands
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ # http://www.nominet.org.uk/registrars/systems/nominetepp/login/
9
+ def login
10
+ unless @logged_in
11
+ builder = Nokogiri::XML::Builder.new do |xml|
12
+ xml.epp("xmlns" => "urn:ietf:params:xml:ns:epp-1.0",
13
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
14
+ "xsi:schemaLocation" => "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd" ) {
15
+ xml.command {
16
+ xml.login {
17
+ xml.clID @tag
18
+ xml.pw @password
19
+ xml.options {
20
+ xml.version "1.0"
21
+ xml.lang "en"
22
+ }
23
+ xml.svcs {
24
+ xml.objURI "http://www.nominet.org.uk/epp/xml/nom-domain-2.0"
25
+ }
26
+ }
27
+ }
28
+ }
29
+ end
30
+ r = self.write( builder.to_xml )
31
+ end
32
+ @logged_in = true
33
+ end
34
+
35
+ def check(*domains)
36
+ login unless @logged_in
37
+ builder = Nokogiri::XML::Builder.new do |xml|
38
+ xml.epp("xmlns" => "urn:ietf:params:xml:ns:epp-1.0",
39
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
40
+ "xsi:schemaLocation" => "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd" ) {
41
+ xml.command {
42
+ xml.check {
43
+ xml.check("xmlns:domain" => "http://www.nominet.org.uk/epp/xml/nom-domain-2.0",
44
+ "xsi:schemaLocation" => "http://www.nominet.org.uk/epp/xml/nom-domain-2.0 nom-domain-2.0.xsd") {
45
+ xml.parent.namespace = xml.parent.namespace_definitions.first
46
+ domains.each {|d|
47
+ xml["domain"].name d
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ end
54
+ r = self.write( builder.to_xml )
55
+ r.response.resdata.chkdata.domain_names.inject({}){|hash,domain|
56
+ hash.merge( domain => r.response.resdata.chkdata.domain_names_avail.shift == "1")
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,47 @@
1
+ require "socket"
2
+ require "openssl"
3
+ require "eventmachine"
4
+
5
+ module Pepper
6
+ module Connection
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ attr_accessor :connection
13
+
14
+ def settings=(opts = {})
15
+ @server = opts[:server]
16
+ @tag = opts[:tag]
17
+ @password = opts[:password]
18
+ @port = opts[:port] || 700
19
+ @lang = opts[:lang] || "en"
20
+
21
+ @logged_in = false
22
+ @parser = nil
23
+ end
24
+
25
+ def connect
26
+ sock = TCPSocket.new( @server, @port )
27
+ ssl_context = OpenSSL::SSL::SSLContext.new
28
+ ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
29
+ self.connection = OpenSSL::SSL::SSLSocket.new( sock, ssl_context )
30
+
31
+ self.connection.sync_close
32
+ self.connection.connect
33
+
34
+ @parser = StreamParser.new self.connection
35
+ @parser.get_frame
36
+
37
+ self.connection
38
+ end
39
+
40
+ def write(xml)
41
+ (@parser && self.connection || self.connect).write(xml)
42
+ @parser.get_frame
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ module Pepper
2
+ module Error
3
+ class ProtocolSyntax < StandardError; end
4
+ class ImplementationSpecificRules < StandardError; end
5
+ class Security < StandardError; end
6
+ class DataManagement < StandardError; end
7
+ class ServerSystem < StandardError; end
8
+ class ConnectionManagement < StandardError; end
9
+
10
+ class UnrecognisedResponse < StandardError; end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module Pepper
2
+ module Stanzas
3
+ class Chkdata
4
+ include SAXMachine
5
+
6
+ elements "domain:name", :as => :domain_names
7
+ elements "domain:name", :value => :avail, :as => :domain_names_avail
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Pepper
2
+ module Stanzas
3
+ class Epp
4
+ include SAXMachine
5
+
6
+ element :greeting
7
+ element :response, :class => Response
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Pepper
2
+ module Stanzas
3
+ class Resdata
4
+ include SAXMachine
5
+
6
+ element "domain:chkData", :as => :chkdata, :class => Chkdata
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Pepper
2
+ module Stanzas
3
+ class Response
4
+ include SAXMachine
5
+
6
+ element :result, :class => Result
7
+ element :result, :as => :result_code, :value => :code
8
+ element :resData, :as => :resdata, :class => Resdata
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Pepper
2
+ module Stanzas
3
+ class Result
4
+ include SAXMachine
5
+
6
+ element :msg
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ require "sax-machine"
2
+ require "pepper/stanzas/chkdata"
3
+ require "pepper/stanzas/resdata"
4
+ require "pepper/stanzas/result"
5
+ require "pepper/stanzas/response"
6
+ require "pepper/stanzas/epp"
@@ -0,0 +1,59 @@
1
+ require "nokogiri"
2
+
3
+ module Pepper
4
+ class StreamParser < Nokogiri::XML::SAX::Document
5
+
6
+ def initialize(stream)
7
+ @stream = stream
8
+ end
9
+
10
+ def get_frame
11
+ @parser = Nokogiri::XML::SAX::PushParser.new self
12
+ @data = ""
13
+ @start, @end = nil
14
+ header = @stream.read(4)
15
+ begin
16
+ d = @stream.read(1)
17
+ @data << d # Nasty: Duplicates data to feed into sax machine, done because sax-machine does not use a push parser
18
+ @parser << d # This parser is used to find the end of the stanza in the stream
19
+ end until @end
20
+ @stanza = Pepper::Stanzas::Epp.parse @data
21
+ parse_response_code @stanza.response unless @stanza.greeting
22
+ @stanza
23
+ end
24
+
25
+ def start_element name, attrs = []
26
+ @start = name unless @start
27
+ end
28
+
29
+ def end_element name
30
+ @end = true if @start == name
31
+ end
32
+
33
+ private
34
+
35
+ def parse_response_code(response)
36
+ code = response.result_code
37
+ msg = response.result.msg.strip
38
+ case code[0].chr
39
+ when "1"
40
+ # Positive completion reply
41
+ when "2"
42
+ # Negative completion reply
43
+ case code[1].chr
44
+ when "0" : raise Error::ProtocolSyntax.new msg
45
+ when "1" : raise Error::ImplentationSpecificRules.new msg
46
+ when "2" : raise Error::Security.new msg
47
+ when "3" : raise Error::DataManagement.new msg
48
+ when "4" : raise Error::ServerSystem.new msg
49
+ when "5" : raise Error::ConnectionManagement.new msg
50
+ else
51
+ raise Error::UnrecognisedResponse.new msg
52
+ end
53
+ else
54
+ raise Error::UnrecognisedResponse.new msg
55
+ end
56
+ end
57
+
58
+ end
59
+ end
data/lib/pepper.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "rubygems"
2
+ gem "sax-machine"
3
+
4
+ require "pepper/stanzas"
5
+ require "pepper/connection"
6
+ require "pepper/commands"
7
+ require "pepper/stream_parser"
8
+ require "pepper/error"
9
+
10
+ Pepper.class_eval do
11
+ include Pepper::Connection
12
+ include Pepper::Commands
13
+ end
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
5
+ <response>
6
+ <result code="1000">
7
+ <msg>Command completed successfully</msg>
8
+ </result>
9
+ <trID>
10
+ <clTRID>ABC-12345</clTRID>
11
+ <svTRID>54321-XYZ</svTRID>
12
+ </trID>
13
+ </response>
14
+ </epp>
@@ -0,0 +1,51 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require "test_helper"
3
+
4
+ class LivePepperTest < Test::Unit::TestCase
5
+
6
+ context "logging in with correct credentials" do
7
+ setup do
8
+ Pepper.settings = YAML.load_file( File.join(File.dirname(__FILE__), "live_settings.yaml" ))
9
+ end
10
+
11
+ should "return true" do
12
+ assert_equal true, Pepper.login
13
+ end
14
+
15
+ context "twice" do
16
+ should "return true" do
17
+ assert_equal true, Pepper.login
18
+ assert_equal true, Pepper.login
19
+ end
20
+ end
21
+ end
22
+
23
+ context "logging in with incorrect credentials" do
24
+ should "raise error" do
25
+ Pepper.settings = YAML.load_file( File.join(File.dirname(__FILE__), "live_settings.yaml" )).merge( :tag => "FOO" )
26
+
27
+ assert_raises Pepper::Error::Security do
28
+ Pepper.login
29
+ end
30
+ end
31
+ end
32
+
33
+ context "command" do
34
+ setup do
35
+ @hash = YAML.load_file( File.join(File.dirname(__FILE__), "live_settings.yaml" ))
36
+ Pepper.settings = @hash
37
+ end
38
+
39
+ context "'check'" do
40
+ should "return available for 'foo.co.uk'" do
41
+ assert_equal( {"foo.co.uk" => true}, Pepper.check( 'foo.co.uk' ))
42
+ end
43
+
44
+ should "return correct hash for 'foo.co.uk', 'bar.co.uk' and 'macduff-TAG.co.uk'" do
45
+ domains = {"foo.co.uk" => true, "bar.co.uk" => true, "macduff-#{@hash[:tag]}.co.uk" => false}
46
+ assert_equal domains, Pepper.check( *domains.keys )
47
+ end
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,4 @@
1
+ :server: testbed-epp.nominet.org.uk
2
+ :port: 700
3
+ :tag: FOO
4
+ :password: secret
@@ -0,0 +1,11 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require "test_helper"
3
+
4
+ class PepperTest < Test::Unit::TestCase
5
+ context "logging in" do
6
+ should "write login stanza" do
7
+ mock( Pepper ).write(anything) { response "login_success" }
8
+ Pepper.login
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join( File.dirname(File.dirname(__FILE__)), "lib" )
2
+
3
+ require "pepper"
4
+
5
+ require "rubygems"
6
+
7
+ require "test/unit"
8
+ require "shoulda"
9
+ require "rr"
10
+ require 'stringio'
11
+
12
+ class Test::Unit::TestCase
13
+ include RR::Adapters::TestUnit
14
+
15
+ def response(name)
16
+ Pepper::Stanzas::Epp.parse File.read( File.join(File.dirname(__FILE__),"fixtures", "#{name}.xml") )
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pepper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Theo Cushion
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-16 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sax-machine
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rr
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: shoulda
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description: Currently supports connecting to Nominet and running checks on domain names
56
+ email: theo@triplegeek.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files: []
62
+
63
+ files:
64
+ - README
65
+ - lib/pepper/commands.rb
66
+ - lib/pepper/connection.rb
67
+ - lib/pepper/error.rb
68
+ - lib/pepper/stanzas/chkdata.rb
69
+ - lib/pepper/stanzas/epp.rb
70
+ - lib/pepper/stanzas/resdata.rb
71
+ - lib/pepper/stanzas/response.rb
72
+ - lib/pepper/stanzas/result.rb
73
+ - lib/pepper/stanzas.rb
74
+ - lib/pepper/stream_parser.rb
75
+ - lib/pepper.rb
76
+ has_rdoc: true
77
+ homepage: http://github.com/theoooo/pepper
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ version:
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.3.5
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Provides a simple interface to Nominets EPP service
104
+ test_files:
105
+ - test/fixtures/login_success.xml
106
+ - test/live_pepper_test.rb
107
+ - test/pepper_test.rb
108
+ - test/test_helper.rb
109
+ - test/live_settings.yaml.example