Class: RETS4R::Auth

Inherits:
Object
  • Object
show all
Defined in:
lib/rets4r/auth.rb

Class Method Summary collapse

Class Method Details

.authenticate(response, username, password, uri, method, requestId, useragent, nc = 0) ⇒ Object

This is the primary method that would normally be used, and while it



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rets4r/auth.rb', line 6

def Auth.authenticate(response, username, password, uri, method, requestId, useragent, nc = 0)
    if response['www-authenticate'].nil? || response['www-authenticate'].empty?
      raise "Missing required header 'www-authenticate'. Got: #{response}"
    end

    authHeader = Auth.parse_header(response['www-authenticate'])

    cnonce = cnonce(useragent, password, requestId, authHeader['nonce'])

    authHash = calculate_digest(username, password, authHeader['realm'], authHeader['nonce'], method, uri, authHeader['qop'], cnonce, nc)

    header = ''
    header << "Digest username=\"#{username}\", "
    header << "realm=\"#{authHeader['realm']}\", "
    header << "qop=\"#{authHeader['qop']}\", "
    header << "uri=\"#{uri}\", "
    header << "nonce=\"#{authHeader['nonce']}\", "
    header << "nc=#{('%08x' % nc)}, "
    header << "cnonce=\"#{cnonce}\", "
    header << "response=\"#{authHash}\", "
    header << "opaque=\"#{authHeader['opaque']}\""

    return header
end

.calculate_digest(username, password, realm, nonce, method, uri, qop = false, cnonce = false, nc = 0) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rets4r/auth.rb', line 31

def Auth.calculate_digest(username, password, realm, nonce, method, uri, qop = false, cnonce = false, nc = 0)
    a1 = "#{username}:#{realm}:#{password}"
    a2 = "#{method}:#{uri}"

    response = '';

    requestId = Auth.request_id unless requestId

    if (qop)
        throw ArgumentException, 'qop requires a cnonce to be provided.' unless cnonce

        response = Digest::MD5.hexdigest("#{Digest::MD5.hexdigest(a1)}:#{nonce}:#{('%08x' % nc)}:#{cnonce}:#{qop}:#{Digest::MD5.hexdigest(a2)}")
    else
        response = Digest::MD5.hexdigest("#{Digest::MD5.hexdigest(a1)}:#{nonce}:#{Digest::MD5.hexdigest(a2)}")
    end

    return response
end

.cnonce(useragent, password, requestId, nonce) ⇒ Object



69
70
71
# File 'lib/rets4r/auth.rb', line 69

def Auth.cnonce(useragent, password, requestId, nonce)
    Digest::MD5.hexdigest("#{useragent}:#{password}:#{requestId}:#{nonce}")
end

.parse_header(header) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rets4r/auth.rb', line 50

def Auth.parse_header(header)
    type = header[0, header.index(' ')]
    args = header[header.index(' '), header.length].strip.split(',')

    parts = {'type' => type}

    args.each do |arg|
        name, value = arg.split('=')

        parts[name.downcase.strip] = value.tr('"', '').strip
    end

    return parts
end

.request_idObject



65
66
67
# File 'lib/rets4r/auth.rb', line 65

def Auth.request_id
    Digest::MD5.hexdigest(Time.new.to_f.to_s)
end