Skip to content

Commit

Permalink
Add PushTransports for service discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
rfc2822 committed Jan 17, 2024
1 parent a3e6877 commit 6d4ea0e
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/at/bitfire/dav4jvm/PropertyRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import at.bitfire.dav4jvm.property.carddav.AddressbookDescription
import at.bitfire.dav4jvm.property.carddav.AddressbookHomeSet
import at.bitfire.dav4jvm.property.carddav.SupportedAddressData
import at.bitfire.dav4jvm.property.push.PushSubscribe
import at.bitfire.dav4jvm.property.push.PushTransports
import at.bitfire.dav4jvm.property.webdav.AddMember
import at.bitfire.dav4jvm.property.webdav.CreationDate
import at.bitfire.dav4jvm.property.webdav.CurrentUserPrincipal
Expand Down Expand Up @@ -81,6 +82,7 @@ object PropertyRegistry {
at.bitfire.dav4jvm.property.carddav.MaxResourceSize.Factory,
Owner.Factory,
PushSubscribe.Factory,
PushTransports.Factory,
QuotaAvailableBytes.Factory,
QuotaUsedBytes.Factory,
ResourceType.Factory,
Expand Down
35 changes: 13 additions & 22 deletions src/main/kotlin/at/bitfire/dav4jvm/property/push/PushSubscribe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.Dav4jvm
import at.bitfire.dav4jvm.HttpUtils
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import at.bitfire.dav4jvm.XmlUtils.propertyName
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.time.Instant
import java.util.logging.Level

class PushSubscribe: Property {

Expand All @@ -25,12 +22,11 @@ class PushSubscribe: Property {
val NAME = Property.Name(NS_WEBDAV_PUSH, "push-subscribe")

val EXPIRES = Property.Name(NS_WEBDAV_PUSH, "expires")
val WEB_PUSH_SUBSCRIPTION = Property.Name(NS_WEBDAV_PUSH, "web-push-subscription")

}

var expires: Instant? = null
var webPushSubscription: WebPushSubscription? = null
var subscription: Subscription? = null


object Factory: PropertyFactory {
Expand All @@ -40,24 +36,19 @@ class PushSubscribe: Property {
override fun create(parser: XmlPullParser): PushSubscribe? {
val subscribe = PushSubscribe()

try {
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1)
when (parser.propertyName()) {
EXPIRES -> {
val expiresDate = XmlUtils.requireReadText(parser)
subscribe.expires = HttpUtils.parseDate(expiresDate)
}
WEB_PUSH_SUBSCRIPTION ->
subscribe.webPushSubscription = WebPushSubscription.Factory.create(parser)
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1)
when (parser.propertyName()) {
EXPIRES -> {
val expiresDate = XmlUtils.requireReadText(parser)
subscribe.expires = HttpUtils.parseDate(expiresDate)
}
eventType = parser.next()
}
} catch (e: XmlPullParserException) {
Dav4jvm.log.log(Level.SEVERE, "Couldn't parse <push-subscribe>", e)
return null
Subscription.NAME ->
subscribe.subscription = Subscription.Factory.create(parser)
}
eventType = parser.next()
}

return subscribe
Expand Down
50 changes: 50 additions & 0 deletions src/main/kotlin/at/bitfire/dav4jvm/property/push/PushTransports.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import at.bitfire.dav4jvm.XmlUtils.propertyName
import org.xmlpull.v1.XmlPullParser

class PushTransports private constructor(
val transports: Set<Property.Name>
): Property {

companion object {
@JvmField
val NAME = Property.Name(NS_WEBDAV_PUSH, "push-transports")

val TRANSPORT = Property.Name(NS_WEBDAV_PUSH, "transport")
val WEB_PUSH = Property.Name(NS_WEBDAV_PUSH, "web-push")
}

fun hasWebPush() = transports.contains(WEB_PUSH)


object Factory: PropertyFactory {

override fun getName() = NAME

override fun create(parser: XmlPullParser): PushTransports {
val transports = mutableListOf<Property.Name>()
XmlUtils.processTag(parser, TRANSPORT) {
val depth = parser.depth
var eventType = parser.eventType
while (!(eventType == XmlPullParser.END_TAG && parser.depth == depth)) {
if (eventType == XmlPullParser.START_TAG && parser.depth == depth + 1)
transports += parser.propertyName()
eventType = parser.next()
}
}
return PushTransports(transports.toSet())
}

}

}
45 changes: 45 additions & 0 deletions src/main/kotlin/at/bitfire/dav4jvm/property/push/Subscription.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser

class Subscription private constructor(
val webPushSubscription: WebPushSubscription
): Property {

companion object {

@JvmField
val NAME = Property.Name(NS_WEBDAV_PUSH, "subscription")

}


object Factory: PropertyFactory {

override fun getName() = NAME

override fun create(parser: XmlPullParser): Subscription? {
// currently we only support WebPushSubscription
var webPushSubscription: WebPushSubscription? = null

XmlUtils.processTag(parser, WebPushSubscription.NAME) {
webPushSubscription = WebPushSubscription.Factory.create(parser)
}

return webPushSubscription?.let {
Subscription(webPushSubscription = it)
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@

package at.bitfire.dav4jvm.property.push

import at.bitfire.dav4jvm.Dav4jvm
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.util.logging.Level

class WebPushSubscription: Property {

Expand All @@ -32,19 +29,11 @@ class WebPushSubscription: Property {

override fun getName() = NAME

override fun create(parser: XmlPullParser): WebPushSubscription? {
val subscription = WebPushSubscription()

try {
subscription.pushResource = XmlUtils.readTextProperty(parser, PUSH_RESOURCE)
} catch (e: XmlPullParserException) {
Dav4jvm.log.log(Level.SEVERE, "Couldn't parse <web-push-subscription>", e)
return null
override fun create(parser: XmlPullParser) =
WebPushSubscription().apply {
pushResource = XmlUtils.readTextProperty(parser, PUSH_RESOURCE)
}

return subscription
}

}

}
4 changes: 4 additions & 0 deletions src/main/kotlin/at/bitfire/dav4jvm/property/push/namespace.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@

package at.bitfire.dav4jvm.property.push

/**
* XML namespace of WebDAV-Push (draft), see:
* https://github.com/bitfireAT/webdav-push/
*/
const val NS_WEBDAV_PUSH = "DAV:Push"
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ data class CurrentUserPrivilegeSet(

override fun getName() = NAME

override fun create(parser: XmlPullParser): CurrentUserPrivilegeSet? {
override fun create(parser: XmlPullParser): CurrentUserPrivilegeSet {
// <!ELEMENT current-user-privilege-set (privilege*)>
// <!ELEMENT privilege ANY>
val privs = CurrentUserPrivilegeSet()
Expand Down
35 changes: 28 additions & 7 deletions src/test/kotlin/at/bitfire/dav4jvm/property/WebPushTest.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package at.bitfire.dav4jvm.property

import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.property.push.NS_WEBDAV_PUSH
import at.bitfire.dav4jvm.property.push.PushSubscribe
import at.bitfire.dav4jvm.property.push.PushTransports
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import java.time.Instant

Expand All @@ -10,15 +14,32 @@ class WebPushTest: PropertyTest() {
@Test
fun testPushSubscribe() {
val results = parseProperty(
"<push-subscribe xmlns=\"DAV:Push\">" +
" <web-push-subscription>\n" +
" <push-resource>https://up.example.net/yohd4yai5Phiz1wi</push-resource>\n" +
" </web-push-subscription>\n" +
" <expires>Wed, 20 Dec 2023 10:03:31 GMT</expires>" +
"</push-subscribe>")
"<push-subscribe xmlns=\"DAV:Push\">" +
" <subscription>" +
" <web-push-subscription>\n" +
" <push-resource>https://up.example.net/yohd4yai5Phiz1wi</push-resource>\n" +
" </web-push-subscription>\n" +
" </subscription>" +
" <expires>Wed, 20 Dec 2023 10:03:31 GMT</expires>" +
"</push-subscribe>")
val result = results.first() as PushSubscribe
assertEquals(Instant.ofEpochSecond(1703066611), result.expires)
assertEquals("https://up.example.net/yohd4yai5Phiz1wi", result.webPushSubscription?.pushResource)
assertEquals("https://up.example.net/yohd4yai5Phiz1wi", result.subscription?.webPushSubscription?.pushResource)
}

@Test
fun testPushTransports() {
val results = parseProperty(
"<push-transports xmlns=\"DAV:Push\">" +
" <transport><something><else/></something></transport>" +
" <transport><web-push/></transport>" +
"</push-transports>")
val result = results.first() as PushTransports
assertEquals(setOf(
Property.Name(NS_WEBDAV_PUSH, "something"),
PushTransports.WEB_PUSH
), result.transports)
assertTrue(result.hasWebPush())
}

}

0 comments on commit 6d4ea0e

Please sign in to comment.