Module version

Module version 

Source
Expand description

Version control types for SCIM resources.

This module provides types and functionality for handling resource versioning and conditional operations, enabling ETag-based concurrency control as specified in RFC 7644 (SCIM 2.0) and RFC 7232 (HTTP ETags).

§ETag Concurrency Control

The version system provides automatic optimistic concurrency control for SCIM resources, preventing lost updates when multiple clients modify the same resource simultaneously. All versions are computed deterministically from resource content using SHA-256 hashing.

§Core Types

§Basic Usage

use scim_server::resource::version::{ScimVersion, ConditionalResult};

// Create version from hash string (for provider-specific versioning)
let version = ScimVersion::from_hash("db-sequence-123");

// Create version from content hash (automatic versioning)
let resource_json = br#"{"id":"123","userName":"john.doe","active":true}"#;
let content_version = ScimVersion::from_content(resource_json);

// Parse from HTTP weak ETag header (client-provided versions)
let etag_version = ScimVersion::parse_http_header("W/\"abc123def\"").unwrap();

// Convert to HTTP weak ETag header (for responses)
let etag_header = version.to_http_header(); // Returns: "W/abc123def"

// Check version equality (for conditional operations)
let matches = version.matches(&etag_version);

§Conditional Operations

use scim_server::resource::version::{ConditionalResult, ScimVersion};
use scim_server::resource::{ResourceProvider, RequestContext};
use serde_json::json;

let context = RequestContext::with_generated_id();
let expected_version = ScimVersion::from_hash("current-version");
let update_data = json!({"userName": "updated.name", "active": false});

// Conditional update with version checking
match provider.conditional_update("User", "123", update_data, &expected_version, &context).await? {
    ConditionalResult::Success(versioned_resource) => {
        println!("Update successful!");
        println!("New weak ETag: {}", versioned_resource.version().to_http_header());
    },
    ConditionalResult::VersionMismatch(conflict) => {
        println!("Version conflict detected!");
        println!("Expected: {}", conflict.expected);
        println!("Current: {}", conflict.current);
        println!("Message: {}", conflict.message);
        // Client should refresh and retry with current version
    },
    ConditionalResult::NotFound => {
        println!("Resource not found");
        // Handle missing resource scenario
    }
}

§HTTP Integration

The version system integrates seamlessly with HTTP weak ETags:

use scim_server::resource::version::ScimVersion;

// Server generates weak ETag for response
let resource_data = br#"{"id":"123","userName":"alice","active":true}"#;
let version = ScimVersion::from_content(resource_data);
let etag_header = version.to_http_header(); // "W/xyz789abc"

// Client provides weak ETag in subsequent request (If-Match header)
let client_etag = "W/\"xyz789abc\"";
let client_version = ScimVersion::parse_http_header(client_etag).unwrap();

// Server validates version before operation
if version.matches(&client_version) {
    println!("Versions match - proceed with operation");
} else {
    println!("Version mismatch - return 412 Precondition Failed");
}

§Version Properties

  • Deterministic: Same content always produces the same version
  • Content-Based: Any change to resource data changes the version
  • Collision-Resistant: SHA-256 based hashing prevents accidental conflicts
  • Compact: Base64 encoded for efficient transmission
  • Opaque: Internal representation prevents manipulation
  • HTTP Compatible: Direct integration with weak ETag headers

Structs§

ScimVersion
Opaque version identifier for SCIM resources.
VersionConflict
Details about a version conflict during a conditional operation.

Enums§

ConditionalResult
Result type for conditional SCIM operations.
VersionError
Errors that can occur during version operations.