Skip to content

Commit 91752b3

Browse files
committed
feat(nextcloud): Implement WebDAV extended MKCOL
Signed-off-by: provokateurin <kate@provokateurin.de>
1 parent f0c74f0 commit 91752b3

File tree

5 files changed

+133
-9
lines changed

5 files changed

+133
-9
lines changed

packages/nextcloud/lib/src/api/webdav/models/webdav.dart

+12
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ class WebDavPropertyupdate with _$WebDavPropertyupdateXmlSerializableMixin {
8888
final WebDavRemove? remove;
8989
}
9090

91+
@immutable
92+
@annotation.XmlSerializable(createMixin: true)
93+
@annotation.XmlRootElement(name: 'mkcol', namespace: namespaceDav)
94+
class WebDavMkcol with _$WebDavMkcolXmlSerializableMixin {
95+
const WebDavMkcol({
96+
this.set,
97+
});
98+
99+
@annotation.XmlElement(name: 'set', namespace: namespaceDav, includeIfNull: false)
100+
final WebDavSet? set;
101+
}
102+
91103
@immutable
92104
@annotation.XmlSerializable(createMixin: true)
93105
@annotation.XmlRootElement(name: 'set', namespace: namespaceDav)

packages/nextcloud/lib/src/api/webdav/models/webdav.g.dart

+66
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/nextcloud/lib/src/api/webdav/webdav_client.dart

+23-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ignore_for_file: non_constant_identifier_names
22

33
import 'dart:async';
4-
import 'dart:convert';
54
import 'dart:typed_data';
65

76
import 'package:http/http.dart' as http;
@@ -62,23 +61,41 @@ class WebDavClient {
6261

6362
/// Returns a request to create a collection at [path].
6463
///
64+
/// The props in [set] will be added.
65+
///
6566
/// See:
66-
/// * http://www.webdav.org/specs/rfc2518.html#METHOD_MKCOL for more information.
67+
/// * http://www.webdav.org/specs/rfc2518.html#METHOD_MKCOL and http://www.webdav.org/specs/rfc5689.html for more information.
6768
/// * [mkcol] for a complete operation executing this request.
68-
http.Request mkcol_Request(PathUri path) {
69+
http.Request mkcol_Request(
70+
PathUri path, {
71+
WebDavProp? set,
72+
}) {
6973
final request = http.Request('MKCOL', _constructUri(path));
74+
if (set != null) {
75+
request.body = WebDavMkcol(
76+
set: WebDavSet(prop: set),
77+
).toXmlElement(namespaces: namespaces).toXmlString();
78+
}
7079

7180
_addBaseHeaders(request);
7281
return request;
7382
}
7483

7584
/// Creates a collection at [path].
7685
///
86+
/// The props in [set] will be added.
87+
///
7788
/// See:
78-
/// * http://www.webdav.org/specs/rfc2518.html#METHOD_MKCOL for more information.
89+
/// * http://www.webdav.org/specs/rfc2518.html#METHOD_MKCOL and http://www.webdav.org/specs/rfc5689.html for more information.
7990
/// * [mkcol_Request] for the request sent by this method.
80-
Future<http.StreamedResponse> mkcol(PathUri path) {
81-
final request = mkcol_Request(path);
91+
Future<http.StreamedResponse> mkcol(
92+
PathUri path, {
93+
WebDavProp? set,
94+
}) {
95+
final request = mkcol_Request(
96+
path,
97+
set: set,
98+
);
8299

83100
return csrfClient.send(request);
84101
}
@@ -412,7 +429,6 @@ class WebDavClient {
412429
WebDavDepth? depth,
413430
}) {
414431
final request = http.Request('PROPFIND', _constructUri(path))
415-
..encoding = utf8
416432
..body = WebDavPropfind(prop: prop ?? const WebDavPropWithoutValues())
417433
.toXmlElement(namespaces: namespaces)
418434
.toXmlString();
@@ -461,7 +477,6 @@ class WebDavClient {
461477
WebDavPropWithoutValues? prop,
462478
}) {
463479
final request = http.Request('REPORT', _constructUri(path))
464-
..encoding = utf8
465480
..body = WebDavOcFilterFiles(
466481
filterRules: filterRules,
467482
prop: prop ?? const WebDavPropWithoutValues(), // coverage:ignore-line
@@ -508,7 +523,6 @@ class WebDavClient {
508523
WebDavPropWithoutValues? remove,
509524
}) {
510525
final request = http.Request('PROPPATCH', _constructUri(path))
511-
..encoding = utf8
512526
..body = WebDavPropertyupdate(
513527
set: set != null ? WebDavSet(prop: set) : null,
514528
remove: remove != null ? WebDavRemove(prop: remove) : null,

packages/nextcloud/test/api/webdav/webdav_test.dart

+20
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,26 @@ void main() {
523523
);
524524
});
525525

526+
test('Extended mkcol', () async {
527+
final response = await tester.client.webdav.mkcol(
528+
PathUri.parse('test/extended-mkcol'),
529+
set: const WebDavProp(
530+
davResourcetype: WebDavResourcetype(collection: [null]),
531+
ocTags: WebDavOcTags(tags: ['extended']),
532+
),
533+
);
534+
expect(response.statusCode, 201);
535+
536+
final propfindResponse = await tester.client.webdav.propfind(
537+
PathUri.parse('test/extended-mkcol'),
538+
prop: const WebDavPropWithoutValues.fromBools(
539+
ocTags: true,
540+
),
541+
);
542+
final props = propfindResponse.responses.single.propstats.first.prop;
543+
expect(props.ocTags!.tags!.single, 'extended');
544+
});
545+
526546
group('litmus', () {
527547
group('basic', () {
528548
test('options', () async {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
MKCOL http://localhost/remote\.php/webdav/test/extended-mkcol
2+
authorization: Bearer mock
3+
content-type: application/xml
4+
ocs-apirequest: true
5+
requesttoken: token
6+
<d:mkcol xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:set><d:prop><d:resourcetype><d:collection/></d:resourcetype><oc:tags><oc:tag>extended</oc:tag></oc:tags></d:prop></d:set></d:mkcol>
7+
PROPFIND http://localhost/remote\.php/webdav/test/extended-mkcol
8+
authorization: Bearer mock
9+
content-type: application/xml
10+
ocs-apirequest: true
11+
requesttoken: token
12+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop><oc:tags/></d:prop></d:propfind>

0 commit comments

Comments
 (0)