dav handler method name

main
Bob Mottram 2022-02-24 10:18:54 +00:00
parent 0b36feebc2
commit 53a72091ae
4 changed files with 181 additions and 3 deletions

View File

@ -16856,7 +16856,7 @@ class PubServer(BaseHTTPRequestHandler):
self._404()
return
if not self._is_authorized():
print('PROPFIND Not authorized')
print(endpoint_type.upper() + ' not authorized')
self._403()
return
nickname = self.path.split('/calendars/')[1]
@ -16877,9 +16877,10 @@ class PubServer(BaseHTTPRequestHandler):
propfind_bytes = self.rfile.read(length)
except SocketError as ex:
if ex.errno == errno.ECONNRESET:
print('EX: PROPFIND connection reset by peer')
print('EX: ' + endpoint_type.upper() +
' connection reset by peer')
else:
print('EX: PROPFIND socket error')
print('EX: ' + endpoint_type.upper() + ' socket error')
self._400()
return
except ValueError as ex:

View File

@ -13,6 +13,7 @@ import sys
import time
import argparse
import getpass
import datetime
from person import get_actor_json
from person import create_person
from person import create_group
@ -101,6 +102,7 @@ from announce import send_announce_via_server
from socnet import instances_graph
from migrate import migrate_accounts
from desktop_client import run_desktop_client
from happening import dav_month_via_server
def str2bool(value_str) -> bool:
@ -115,6 +117,7 @@ def str2bool(value_str) -> bool:
raise argparse.ArgumentTypeError('Boolean value expected.')
search_date = datetime.datetime.now()
parser = argparse.ArgumentParser(description='ActivityPub Server')
parser.add_argument('--content_license_url', type=str,
default='https://creativecommons.org/licenses/by/4.0',
@ -172,6 +175,12 @@ parser.add_argument('--i2p_domain', dest='i2p_domain', type=str,
parser.add_argument('-p', '--port', dest='port', type=int,
default=None,
help='Port number to run on')
parser.add_argument('--year', dest='year', type=int,
default=search_date.year,
help='Year for calendar query')
parser.add_argument('--month', dest='month', type=int,
default=search_date.month,
help='Month for calendar query')
parser.add_argument('--postsPerSource',
dest='max_newswire_postsPerSource', type=int,
default=4,
@ -329,6 +338,11 @@ parser.add_argument("--repliesEnabled", "--commentsEnabled",
type=str2bool, nargs='?',
const=True, default=True,
help="Enable replies to a post")
parser.add_argument("--dav",
dest='dav',
type=str2bool, nargs='?',
const=True, default=False,
help="Caldav")
parser.add_argument("--show_publish_as_icon",
dest='show_publish_as_icon',
type=str2bool, nargs='?',
@ -1375,6 +1389,47 @@ if args.message:
time.sleep(1)
sys.exit()
if args.dav:
if not args.nickname:
print('Please specify a nickname with --nickname')
sys.exit()
if not args.domain:
print('Please specify a domain with --domain')
sys.exit()
if not args.year:
print('Please specify a year with --year')
sys.exit()
if not args.month:
print('Please specify a month with --month')
sys.exit()
if not args.password:
args.password = getpass.getpass('Password: ')
if not args.password:
print('Specify a password with the --password option')
sys.exit()
args.password = args.password.replace('\n', '')
proxy_type = None
if args.tor or domain.endswith('.onion'):
proxy_type = 'tor'
if domain.endswith('.onion'):
args.port = 80
elif args.i2p or domain.endswith('.i2p'):
proxy_type = 'i2p'
if domain.endswith('.i2p'):
args.port = 80
elif args.gnunet:
proxy_type = 'gnunet'
session = create_session(proxy_type)
result = \
dav_month_via_server(session, http_prefix,
args.nickname, args.domain, args.port,
args.debug,
args.year, args.month,
args.password)
if result:
print(str(result))
sys.exit()
if args.announce:
if not args.nickname:
print('Specify a nickname with the --nickname option')

View File

@ -23,8 +23,11 @@ from utils import remove_html
from utils import get_display_name
from utils import delete_post
from utils import get_status_number
from utils import get_full_domain
from filters import is_filtered
from context import get_individual_post_context
from session import get_method
from auth import create_basic_auth_header
def _dav_date_from_string(timestamp: str) -> str:
@ -1259,3 +1262,45 @@ def dav_delete_response(base_dir: str, nickname: str, domain: str,
nickname, domain, post_filename,
debug, recent_posts_cache)
return 'Ok'
def dav_month_via_server(session, http_prefix: str,
nickname: str, domain: str, port: int,
debug: bool,
year: int, month: int,
password: str) -> str:
"""Gets the icalendar for a month via caldav
"""
auth_header = create_basic_auth_header(nickname, password)
headers = {
'host': domain,
'Content-type': 'application/xml',
'Authorization': auth_header
}
domain_full = get_full_domain(domain, port)
params = {}
url = http_prefix + '://' + domain_full + '/calendars/' + nickname
month_str = str(month)
if month < 10:
month_str = '0' + month_str
xml_str = \
'<?xml version="1.0" encoding="utf-8" ?>\n' + \
'<c:calendar-query xmlns:d="DAV:"\n' + \
' xmlns:c="urn:ietf:params:xml:ns:caldav">\n' + \
' <d:prop>\n' + \
' <d:getetag/>\n' + \
' </d:prop>\n' + \
' <c:filter>\n' + \
' <c:comp-filter name="VCALENDAR">\n' + \
' <c:comp-filter name="VEVENT">\n' + \
' <c:time-range start="' + str(year) + month_str + \
'01T000000Z"\n' + \
' end="' + str(year) + month_str + \
'31T000000Z"/>\n' + \
' </c:comp-filter>\n' + \
' </c:comp-filter>\n' + \
' </c:filter>\n' + \
'</c:calendar-query>'
result = get_method("REPORT", xml_str, session, url, params, debug)
return result

View File

@ -664,3 +664,80 @@ def download_image_any_mime_type(session, url: str,
if 'image/' + m_type in content_type:
mime_type = 'image/' + m_type
return result.content, mime_type
def get_method(method_name: str, xml_str: str,
session, url: str, params: {}, debug: bool,
version: str = '1.3.0', http_prefix: str = 'https',
domain: str = 'testdomain',
timeout_sec: int = 20, quiet: bool = False) -> {}:
if method_name not in ("REPORT", "PUT", "PROPFIND"):
print("Unrecognized method: " + method_name)
return None
if not isinstance(url, str):
if debug and not quiet:
print('url: ' + str(url))
print('ERROR: get_method failed, url should be a string')
return None
headers = {
'Accept': 'application/xml'
}
session_params = {}
session_headers = {}
if headers:
session_headers = headers
if params:
session_params = params
session_headers['User-Agent'] = 'Epicyon/' + version
if domain:
session_headers['User-Agent'] += \
'; +' + http_prefix + '://' + domain + '/'
if not session:
if not quiet:
print('WARN: get_method failed, no session specified for get_vcard')
return None
if debug:
HTTPConnection.debuglevel = 1
try:
result = session.request(method_name, url, headers=session_headers,
data=xml_str,
params=session_params, timeout=timeout_sec)
if result.status_code != 200 and result.status_code != 207:
if result.status_code == 401:
print("WARN: get_method " + url + ' rejected by secure mode')
elif result.status_code == 403:
print('WARN: get_method Forbidden url: ' + url)
elif result.status_code == 404:
print('WARN: get_method Not Found url: ' + url)
elif result.status_code == 410:
print('WARN: get_method no longer available url: ' + url)
else:
print('WARN: get_method url: ' + url +
' failed with error code ' +
str(result.status_code) +
' headers: ' + str(session_headers))
return result.content.decode('utf-8')
except requests.exceptions.RequestException as ex:
session_headers2 = session_headers.copy()
if session_headers2.get('Authorization'):
session_headers2['Authorization'] = 'REDACTED'
if debug and not quiet:
print('EX: get_method failed, url: ' + str(url) + ', ' +
'headers: ' + str(session_headers2) + ', ' +
'params: ' + str(session_params) + ', ' + str(ex))
except ValueError as ex:
session_headers2 = session_headers.copy()
if session_headers2.get('Authorization'):
session_headers2['Authorization'] = 'REDACTED'
if debug and not quiet:
print('EX: get_method failed, url: ' + str(url) + ', ' +
'headers: ' + str(session_headers2) + ', ' +
'params: ' + str(session_params) + ', ' + str(ex))
except SocketError as ex:
if not quiet:
if ex.errno == errno.ECONNRESET:
print('EX: get_method failed, ' +
'connection was reset during get_vcard ' + str(ex))
return None