250 lines
7.4 KiB
Plaintext
250 lines
7.4 KiB
Plaintext
$OpenBSD: patch-lib_agcaldav_client_rb,v 1.2 2013/03/18 21:45:41 jasper Exp $
|
|
|
|
commit c13ea74da87d56c526f0187abe30e9d185f43374
|
|
Author: Geoff Evans <gbeevans@me.com>
|
|
Date: Wed Feb 20 11:01:50 2013 +1300
|
|
Subject:Adds Digest Authentication
|
|
|
|
commit 20687529a3c3554d0f51dabd81e06b172a96b940
|
|
Author: Geoff Evans <gbeevans@me.com>
|
|
Date: Wed Mar 6 12:34:46 2013 +1300
|
|
Subject:Fix Digest to work over ssl.
|
|
|
|
commit 7b411e884b3884ca1f49338e1e2f12925c58ae0d
|
|
Author: Geoff Evans <gbeevans@me.com>
|
|
Date: Tue Mar 19 10:08:31 2013 +1300
|
|
Subject:Fix find_events for pure ruby
|
|
|
|
--- lib/agcaldav/client.rb.orig Thu Jan 1 01:00:00 1970
|
|
+++ lib/agcaldav/client.rb Mon Mar 18 22:31:42 2013
|
|
@@ -17,6 +17,7 @@ module AgCalDAV
|
|
@proxy_host = proxy_uri.host
|
|
@proxy_port = proxy_uri.port.to_i
|
|
end
|
|
+
|
|
uri = URI(data[:uri])
|
|
@host = uri.host
|
|
@port = uri.port.to_i
|
|
@@ -24,6 +25,24 @@ module AgCalDAV
|
|
@user = data[:user]
|
|
@password = data[:password]
|
|
@ssl = uri.scheme == 'https'
|
|
+
|
|
+ unless data[:authtype].nil?
|
|
+ @authtype = data[:authtype]
|
|
+ if @authtype == 'digest'
|
|
+
|
|
+ @digest_auth = Net::HTTP::DigestAuth.new
|
|
+ @duri = URI.parse data[:uri]
|
|
+ @duri.user = @user
|
|
+ @duri.password = @password
|
|
+
|
|
+ elsif @authtype == 'basic'
|
|
+ #Don't Raise or do anything else
|
|
+ else
|
|
+ raise "Authentication Type Specified Is Not Valid. Please use basic or digest"
|
|
+ end
|
|
+ else
|
|
+ @authtype = 'basic'
|
|
+ end
|
|
end
|
|
|
|
def __create_http
|
|
@@ -44,14 +63,26 @@ module AgCalDAV
|
|
events = []
|
|
res = nil
|
|
__create_http.start {|http|
|
|
+
|
|
req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
|
|
- req.basic_auth @user, @password
|
|
- req.body = AgCalDAV::Request::ReportVEVENT.new(DateTime.parse(data[:start]).strftime("%Y%m%dT%H%M"),
|
|
- DateTime.parse(data[:end]).strftime("%Y%m%dT%H%M") ).to_xml
|
|
+
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('REPORT')
|
|
+ end
|
|
+ if data[:start].is_a? Integer
|
|
+ req.body = AgCalDAV::Request::ReportVEVENT.new(Time.at(data[:start]).utc.strftime("%Y%m%dT%H%M%S"),
|
|
+ Time.at(data[:end]).utc.strftime("%Y%m%dT%H%M%S") ).to_xml
|
|
+ else
|
|
+ req.body = AgCalDAV::Request::ReportVEVENT.new(DateTime.parse(data[:start]).utc.strftime("%Y%m%dT%H%M%S"),
|
|
+ DateTime.parse(data[:end]).utc.strftime("%Y%m%dT%H%M%S") ).to_xml
|
|
+ end
|
|
res = http.request(req)
|
|
}
|
|
errorhandling res
|
|
result = ""
|
|
+
|
|
xml = REXML::Document.new(res.body)
|
|
REXML::XPath.each( xml, '//c:calendar-data/', {"c"=>"urn:ietf:params:xml:ns:caldav"} ){|c| result << c.text}
|
|
r = Icalendar.parse(result)
|
|
@@ -70,16 +101,21 @@ module AgCalDAV
|
|
def find_event uuid
|
|
res = nil
|
|
__create_http.start {|http|
|
|
- req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
|
|
- req.basic_auth @user, @password
|
|
+ req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('GET')
|
|
+ end
|
|
res = http.request( req )
|
|
}
|
|
errorhandling res
|
|
- r = Icalendar.parse(res.body)
|
|
- unless r.empty?
|
|
- r.first.events.first
|
|
+ begin
|
|
+ r = Icalendar.parse(res.body)
|
|
+ rescue
|
|
+ return false
|
|
else
|
|
- return false
|
|
+ r.first.events.first
|
|
end
|
|
|
|
|
|
@@ -89,7 +125,11 @@ module AgCalDAV
|
|
res = nil
|
|
__create_http.start {|http|
|
|
req = Net::HTTP::Delete.new("#{@url}/#{uuid}.ics")
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('DELETE')
|
|
+ end
|
|
res = http.request( req )
|
|
}
|
|
errorhandling res
|
|
@@ -126,7 +166,11 @@ module AgCalDAV
|
|
__create_http.start { |http|
|
|
req = Net::HTTP::Put.new("#{@url}/#{uuid}.ics")
|
|
req['Content-Type'] = 'text/calendar'
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('PUT')
|
|
+ end
|
|
req.body = cstring
|
|
res = http.request( req )
|
|
}
|
|
@@ -147,19 +191,15 @@ module AgCalDAV
|
|
|
|
end
|
|
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
def find_todo uuid
|
|
res = nil
|
|
__create_http.start {|http|
|
|
req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('GET')
|
|
+ end
|
|
res = http.request( req )
|
|
}
|
|
errorhandling res
|
|
@@ -196,7 +236,11 @@ module AgCalDAV
|
|
__create_http.start { |http|
|
|
req = Net::HTTP::Put.new("#{@url}/#{uuid}.ics")
|
|
req['Content-Type'] = 'text/calendar'
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('PUT')
|
|
+ end
|
|
req.body = cstring
|
|
res = http.request( req )
|
|
}
|
|
@@ -210,7 +254,11 @@ module AgCalDAV
|
|
|
|
__create_http.start {|http|
|
|
req = Net::HTTP::Report.new(@url, initheader = {'Content-Type'=>'application/xml'} )
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('REPORT')
|
|
+ end
|
|
req.body = AgCalDAV::Request::ReportVTODO.new.to_xml
|
|
res = http.request( req )
|
|
}
|
|
@@ -219,29 +267,52 @@ module AgCalDAV
|
|
end
|
|
|
|
private
|
|
+
|
|
+ def digestauth method
|
|
+
|
|
+ h = Net::HTTP.new @duri.host, @duri.port
|
|
+ if @ssl
|
|
+ h.use_ssl = @ssl
|
|
+ h.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
+ end
|
|
+ req = Net::HTTP::Get.new @duri.request_uri
|
|
+
|
|
+ res = h.request req
|
|
+ # res is a 401 response with a WWW-Authenticate header
|
|
+
|
|
+ auth = @digest_auth.auth_header @duri, res['www-authenticate'], method
|
|
+
|
|
+ return auth
|
|
+ end
|
|
+
|
|
def entry_with_uuid_exists? uuid
|
|
res = nil
|
|
+
|
|
__create_http.start {|http|
|
|
req = Net::HTTP::Get.new("#{@url}/#{uuid}.ics")
|
|
- req.basic_auth @user, @password
|
|
+ if not @authtype == 'digest'
|
|
+ req.basic_auth @user, @password
|
|
+ else
|
|
+ req.add_field 'Authorization', digestauth('GET')
|
|
+ end
|
|
+
|
|
res = http.request( req )
|
|
- }
|
|
- if res.body.empty?
|
|
- return false
|
|
+
|
|
+ }
|
|
+ begin
|
|
+ Icalendar.parse(res.body)
|
|
+ rescue
|
|
+ return false
|
|
else
|
|
- return true
|
|
+ return true
|
|
end
|
|
end
|
|
-
|
|
def errorhandling response
|
|
raise AuthenticationError if response.code.to_i == 401
|
|
raise NotExistError if response.code.to_i == 410
|
|
raise APIError if response.code.to_i >= 500
|
|
end
|
|
end
|
|
-
|
|
-
|
|
-
|
|
|
|
|
|
class AgCalDAVError < StandardError
|