feat(protocol): define native session credentials
This commit is contained in:
@@ -35,6 +35,9 @@ let capability = try CapabilityProfile(
|
||||
transport: "quic-tls13", framing: "datagram-v1", media: "encoded",
|
||||
audio: "encoded", sourceRateControl: "server", clientDecode: ["h264-opus"]
|
||||
)
|
||||
guard currentWireVersion == "2", nMinus1WireVersion == "1", nMinus2WireVersion == "0" else {
|
||||
fatalError("unexpected control wire compatibility declaration")
|
||||
}
|
||||
_ = try CapabilityProfile(
|
||||
transport: "quic-tls13", framing: "datagram-v2", media: "encoded",
|
||||
audio: "encoded", sourceRateControl: "server", clientDecode: ["h264-opus"]
|
||||
@@ -114,23 +117,16 @@ for invalid in [
|
||||
fatalError("invalid display mode was accepted")
|
||||
} catch { }
|
||||
}
|
||||
let allocationPolicy = try AllocationPolicy(
|
||||
minimumKbps: 1000, targetKbps: 2000, maximumKbps: 3000, tier: "standard",
|
||||
audience: "versevdi-gateway", protocolValue: "verse", protocolVersion: 1,
|
||||
grantTtlSeconds: 60, reservationLeaseSeconds: 300
|
||||
)
|
||||
let legacyDisplayRequest = try SessionRequest(
|
||||
let policyFreeV2Request = try SessionRequest(
|
||||
clientDeviceId: "device-1", deviceKeyId: "key-1", poolId: "pool-1",
|
||||
idempotencyKey: "request-1", policySnapshot: allocationPolicy,
|
||||
requestedDisplayMode: nil
|
||||
idempotencyKey: "request-1", requestedDisplayMode: nil
|
||||
).encodeJSON()
|
||||
guard !String(data: legacyDisplayRequest, encoding: .utf8)!.contains("requested_display_mode") else {
|
||||
fatalError("legacy request encoded an absent display mode")
|
||||
guard !String(data: policyFreeV2Request, encoding: .utf8)!.contains("requested_display_mode") else {
|
||||
fatalError("wire-v2 request encoded an absent display mode")
|
||||
}
|
||||
let displayRequest = try SessionRequest(
|
||||
clientDeviceId: "device-1", deviceKeyId: "key-1", poolId: "pool-1",
|
||||
idempotencyKey: "request-1", policySnapshot: allocationPolicy,
|
||||
requestedDisplayMode: displayMode
|
||||
idempotencyKey: "request-1", requestedDisplayMode: displayMode
|
||||
)
|
||||
guard try SessionRequest.decodeJSON(displayRequest.encodeJSON()).requestedDisplayMode == displayMode else {
|
||||
fatalError("display mode did not round-trip")
|
||||
@@ -141,6 +137,52 @@ do {
|
||||
_ = try SessionRequest.decodeJSON(try JSONSerialization.data(withJSONObject: nullDisplayRequest))
|
||||
fatalError("explicit null display mode was accepted")
|
||||
} catch { }
|
||||
let nativeIdentity = try NativeSessionIdentity(clientDeviceId: "device-1", deviceKeyId: "key-1")
|
||||
let browserSession = try BrowserAuthenticatedSession(
|
||||
username: "alice", provider: "local", roles: ["user"], role: "user"
|
||||
)
|
||||
guard !String(data: try browserSession.encodeJSON(), encoding: .utf8)!.contains("native_identity") else {
|
||||
fatalError("browser session encoded native identity")
|
||||
}
|
||||
let nativeSession = try NativeAuthenticatedSession(
|
||||
username: "alice", provider: "local", roles: ["user"], role: "user", nativeIdentity: nativeIdentity
|
||||
)
|
||||
guard try NativeAuthenticatedSession.decodeJSON(nativeSession.encodeJSON()).nativeIdentity == nativeIdentity else {
|
||||
fatalError("native session identity did not round-trip")
|
||||
}
|
||||
do {
|
||||
_ = try BrowserAuthenticatedSession.decodeJSON(nativeSession.encodeJSON())
|
||||
fatalError("browser session accepted native identity")
|
||||
} catch { }
|
||||
do {
|
||||
_ = try NativeAuthenticatedSession.decodeJSON(browserSession.encodeJSON())
|
||||
fatalError("native session accepted missing identity")
|
||||
} catch { }
|
||||
var partialNativeSession = try JSONSerialization.jsonObject(with: nativeSession.encodeJSON()) as! [String: Any]
|
||||
partialNativeSession["native_identity"] = ["client_device_id": "device-1"]
|
||||
do {
|
||||
_ = try NativeAuthenticatedSession.decodeJSON(try JSONSerialization.data(withJSONObject: partialNativeSession))
|
||||
fatalError("partial native identity was accepted")
|
||||
} catch { }
|
||||
for roles in [[""], [String(repeating: "r", count: 65)]] {
|
||||
do {
|
||||
_ = try BrowserAuthenticatedSession(username: "alice", provider: "local", roles: roles, role: "user")
|
||||
fatalError("invalid role item length was accepted")
|
||||
} catch { }
|
||||
}
|
||||
_ = try NativeTunnelCredential(
|
||||
clientDeviceId: "device-1", deviceKeyId: "key-1", certificateChainPem: "certificate",
|
||||
trustBundlePem: "trust", expiresAt: "2099-01-01T00:00:00Z"
|
||||
)
|
||||
for expiresAt in ["2099-01-01T00:00:00+00:00", "2099-01-01T00:00:00.100Z"] {
|
||||
do {
|
||||
_ = try NativeTunnelCredential(
|
||||
clientDeviceId: "device-1", deviceKeyId: "key-1", certificateChainPem: "certificate",
|
||||
trustBundlePem: "trust", expiresAt: expiresAt
|
||||
)
|
||||
fatalError("noncanonical RFC3339 UTC timestamp was accepted")
|
||||
} catch { }
|
||||
}
|
||||
let streamPolicy = try ProviderStreamPolicy(
|
||||
resolutionWidth: 2560, resolutionHeight: 1440, fps: 120,
|
||||
codec: "HEVC", bitrateKbps: 40000, audioEnabled: true
|
||||
@@ -207,6 +249,9 @@ do {
|
||||
output.write(
|
||||
"""
|
||||
fn main() {
|
||||
assert_eq!(CURRENT_WIRE_VERSION, "2");
|
||||
assert_eq!(N_MINUS_1_WIRE_VERSION, "1");
|
||||
assert_eq!(N_MINUS_2_WIRE_VERSION, "0");
|
||||
let capabilities = CapabilityProfile::new(
|
||||
"quic-tls13".into(), "datagram-v1".into(), "encoded".into(),
|
||||
"encoded".into(), "server".into(), vec!["h264-opus".into()],
|
||||
@@ -260,20 +305,39 @@ fn main() {
|
||||
assert!(DisplayMode::new(319, 1440, 120).is_err());
|
||||
assert!(DisplayMode::new(2560, 199, 120).is_err());
|
||||
assert!(DisplayMode::new(2560, 1440, 241).is_err());
|
||||
let allocation_policy = AllocationPolicy::new(
|
||||
1000, 2000, 3000, "standard".into(), "versevdi-gateway".into(),
|
||||
"verse".into(), 1, 60, 300,
|
||||
).unwrap();
|
||||
let legacy_display_request = SessionRequest::new(
|
||||
let policy_free_v2_request = SessionRequest::new(
|
||||
"device-1".into(), "key-1".into(), "pool-1".into(), "request-1".into(),
|
||||
allocation_policy.clone(), None,
|
||||
None,
|
||||
).unwrap();
|
||||
assert!(legacy_display_request.requestedDisplayMode().is_none());
|
||||
assert!(policy_free_v2_request.requestedDisplayMode().is_none());
|
||||
let display_request = SessionRequest::new(
|
||||
"device-1".into(), "key-1".into(), "pool-1".into(), "request-1".into(),
|
||||
allocation_policy, Some(display_mode.clone()),
|
||||
Some(display_mode.clone()),
|
||||
).unwrap();
|
||||
assert_eq!(display_request.requestedDisplayMode(), &Some(display_mode));
|
||||
let native_identity = NativeSessionIdentity::new("device-1".into(), "key-1".into()).unwrap();
|
||||
assert!(BrowserAuthenticatedSession::new(
|
||||
"alice".into(), "local".into(), vec!["user".into()], "user".into(),
|
||||
).is_ok());
|
||||
assert!(NativeAuthenticatedSession::new(
|
||||
"alice".into(), "local".into(), vec!["user".into()], "user".into(), native_identity,
|
||||
).is_ok());
|
||||
assert!(BrowserAuthenticatedSession::new(
|
||||
"alice".into(), "local".into(), vec![String::new()], "user".into(),
|
||||
).is_err());
|
||||
assert!(BrowserAuthenticatedSession::new(
|
||||
"alice".into(), "local".into(), vec!["r".repeat(65)], "user".into(),
|
||||
).is_err());
|
||||
assert!(NativeTunnelCredential::new(
|
||||
"device-1".into(), "key-1".into(), "certificate".into(), "trust".into(),
|
||||
"2099-01-01T00:00:00Z".into(),
|
||||
).is_ok());
|
||||
for expires_at in ["2099-01-01T00:00:00+00:00", "2099-01-01T00:00:00.100Z"] {
|
||||
assert!(NativeTunnelCredential::new(
|
||||
"device-1".into(), "key-1".into(), "certificate".into(), "trust".into(),
|
||||
expires_at.into(),
|
||||
).is_err());
|
||||
}
|
||||
assert!(ProviderStreamPolicy::new(
|
||||
2560, 1440, 120, "HEVC".into(), 40000, true,
|
||||
).is_ok());
|
||||
|
||||
Reference in New Issue
Block a user