StandardResourceProvider

Struct StandardResourceProvider 

Source
pub struct StandardResourceProvider<S: StorageProvider> { /* private fields */ }
Expand description

Standard resource provider with pluggable storage backend.

This provider separates SCIM protocol logic from storage concerns by delegating data persistence to a StorageProvider implementation while handling all SCIM-specific business logic, validation, and metadata management.

Implementations§

Source§

impl<S: StorageProvider> StandardResourceProvider<S>

Source

pub fn new(storage: S) -> Self

Create a new standard provider with the given storage backend.

Source

pub async fn clear(&self)

Clear all data from storage.

Removes all resources from all tenants by delegating to the storage backend’s clear operation. This method provides a consistent interface for clearing data regardless of the underlying storage implementation.

§Behavior
  • Delegates to StorageProvider::clear for actual data removal
  • Logs warnings if the clear operation fails
  • Primarily intended for testing scenarios
  • After successful clearing, get_stats should report zero resources
§Examples
use scim_server::providers::StandardResourceProvider;
use scim_server::storage::InMemoryStorage;

let storage = InMemoryStorage::new();
let provider = StandardResourceProvider::new(storage);

// ... create some resources ...
provider.clear().await;

let stats = provider.get_stats().await;
assert_eq!(stats.total_resources, 0);
Source

pub async fn get_stats(&self) -> ProviderStats

Get comprehensive statistics about stored data across all tenants.

Dynamically discovers all tenants and resource types from storage to provide accurate statistics without relying on hardcoded patterns. This method uses the storage provider’s discovery capabilities to enumerate actual data.

§Returns

ProviderStats containing:

  • tenant_count: Number of tenants with at least one resource
  • total_resources: Sum of all resources across all tenants and types
  • resource_type_count: Number of distinct resource types found
  • resource_types: List of all resource type names
§Errors

This method handles storage errors gracefully by using default values (empty collections) when discovery operations fail.

§Examples
use scim_server::providers::StandardResourceProvider;
use scim_server::storage::InMemoryStorage;
use scim_server::resource::{RequestContext, TenantContext};

let storage = InMemoryStorage::new();
let provider = StandardResourceProvider::new(storage);

// ... create resources in multiple tenants ...

let stats = provider.get_stats().await;
println!("Total resources: {}", stats.total_resources);
println!("Active tenants: {}", stats.tenant_count);
println!("Resource types: {:?}", stats.resource_types);
Source

pub async fn list_resources_in_tenant( &self, tenant_id: &str, resource_type: &str, ) -> Vec<Resource>

List all resources of a specific type in a tenant.

Trait Implementations§

Source§

impl<S: Clone + StorageProvider> Clone for StandardResourceProvider<S>

Source§

fn clone(&self) -> StandardResourceProvider<S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S: Debug + StorageProvider> Debug for StandardResourceProvider<S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S: StorageProvider> ResourceProvider for StandardResourceProvider<S>

Source§

type Error = ProviderError

Error type returned by all provider operations
Source§

async fn create_resource( &self, resource_type: &str, data: Value, context: &RequestContext, ) -> Result<VersionedResource, Self::Error>

Create a resource for the tenant specified in the request context. Read more
Source§

async fn get_resource( &self, resource_type: &str, id: &str, context: &RequestContext, ) -> Result<Option<VersionedResource>, Self::Error>

Get a resource by ID from the tenant specified in the request context. Read more
Source§

async fn update_resource( &self, resource_type: &str, id: &str, data: Value, expected_version: Option<&RawVersion>, context: &RequestContext, ) -> Result<VersionedResource, Self::Error>

Update a resource in the tenant specified in the request context. Read more
Source§

async fn delete_resource( &self, resource_type: &str, id: &str, expected_version: Option<&RawVersion>, context: &RequestContext, ) -> Result<(), Self::Error>

Delete a resource from the tenant specified in the request context. Read more
Source§

async fn list_resources( &self, resource_type: &str, query: Option<&ListQuery>, context: &RequestContext, ) -> Result<Vec<VersionedResource>, Self::Error>

List resources from the tenant specified in the request context. Read more
Source§

async fn find_resources_by_attribute( &self, resource_type: &str, attribute_name: &str, attribute_value: &str, context: &RequestContext, ) -> Result<Vec<VersionedResource>, Self::Error>

Find resources by attribute value within the tenant specified in the request context. Read more
Source§

async fn patch_resource( &self, resource_type: &str, id: &str, patch_request: &Value, expected_version: Option<&RawVersion>, context: &RequestContext, ) -> Result<VersionedResource, Self::Error>

Apply a PATCH operation to a resource. Read more
Source§

async fn resource_exists( &self, resource_type: &str, id: &str, context: &RequestContext, ) -> Result<bool, Self::Error>

Check if a resource exists within the tenant specified in the request context. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ConditionalOperations for T

Source§

fn conditional_update_resource( &self, resource_type: &str, id: &str, data: Value, expected_version: &RawVersion, context: &RequestContext, ) -> impl Future<Output = Result<ConditionalResult<VersionedResource>, Self::Error>> + Send
where Self: Sync,

Perform a conditional update operation. Read more
Source§

fn conditional_delete_resource( &self, resource_type: &str, id: &str, expected_version: &RawVersion, context: &RequestContext, ) -> impl Future<Output = Result<ConditionalResult<()>, Self::Error>> + Send
where Self: Sync,

Perform a conditional delete operation. Read more
Source§

fn conditional_patch_resource( &self, resource_type: &str, id: &str, patch_request: &Value, expected_version: &RawVersion, context: &RequestContext, ) -> impl Future<Output = Result<ConditionalResult<VersionedResource>, Self::Error>> + Send
where Self: Sync,

Perform a conditional PATCH operation. Read more
Source§

fn get_versioned_resource( &self, resource_type: &str, id: &str, context: &RequestContext, ) -> impl Future<Output = Result<Option<VersionedResource>, Self::Error>> + Send
where Self: Sync,

Get a resource with its version information. Read more
Source§

fn create_versioned_resource( &self, resource_type: &str, data: Value, context: &RequestContext, ) -> impl Future<Output = Result<VersionedResource, Self::Error>> + Send
where Self: Sync,

Create a resource with version information. Read more
Source§

fn check_resource_version( &self, resource_type: &str, id: &str, expected_version: &RawVersion, context: &RequestContext, ) -> impl Future<Output = Result<Option<bool>, Self::Error>> + Send
where Self: Sync,

Check if a resource version matches the expected version. Read more
Source§

fn get_resource_version( &self, resource_type: &str, id: &str, context: &RequestContext, ) -> impl Future<Output = Result<Option<RawVersion>, Self::Error>> + Send
where Self: Sync,

Get the current version of a resource without retrieving the full resource. Read more
Source§

fn is_valid_version(&self, version: &RawVersion) -> bool

Validate that a version is in the expected format. Read more
Source§

fn create_version_conflict( &self, expected: RawVersion, current: RawVersion, resource_info: Option<&str>, ) -> VersionConflict

Create a version conflict error with standard messaging. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MultiTenantProvider for T

Source§

fn effective_tenant_id(&self, context: &RequestContext) -> String

Get the effective tenant ID for an operation. Read more
Source§

fn tenant_scoped_key( &self, tenant_id: &str, resource_type: &str, resource_id: &str, ) -> String

Create a tenant-scoped storage key. Read more
Source§

fn tenant_scoped_prefix(&self, tenant_id: &str, resource_type: &str) -> String

Create a tenant-scoped prefix for listing operations. Read more
Source§

fn is_valid_tenant_context( &self, context: &RequestContext, require_tenant: bool, ) -> bool

Validate that a request context is appropriate for multi-tenant operations. Read more
Source§

fn extract_tenant_context<'a>( &self, context: &'a RequestContext, ) -> Option<&'a TenantContext>

Extract tenant context information from a request context. Read more
Source§

fn generate_tenant_resource_id( &self, _tenant_id: &str, _resource_type: &str, ) -> String

Generate a unique resource ID within a tenant scope. Read more
Source§

fn same_tenant( &self, context1: &RequestContext, context2: &RequestContext, ) -> bool

Check if two request contexts belong to the same tenant. Read more
Source§

fn tenant_error_message( &self, context: &RequestContext, base_message: &str, ) -> String

Create a tenant-specific error message. Read more
Source§

fn is_single_tenant_context(&self, context: &RequestContext) -> bool

Check if the provider is operating in single-tenant mode for a context. Read more
Source§

fn is_multi_tenant_context(&self, context: &RequestContext) -> bool

Check if the provider is operating in multi-tenant mode for a context. Read more
Source§

fn get_client_id<'a>(&self, context: &'a RequestContext) -> Option<&'a str>

Get the client ID associated with a tenant context. Read more
Source§

fn normalize_tenant_id(&self, tenant_id: &str) -> String

Normalize a tenant ID for consistent storage and comparison. Read more
Source§

fn is_valid_tenant_id(&self, tenant_id: &str) -> bool

Validate that a tenant ID meets format requirements. Read more
Source§

impl<T> ResourceProviderExt for T

Source§

fn create_single_tenant( &self, resource_type: &str, data: Value, request_id: Option<String>, ) -> impl Future<Output = Result<VersionedResource, Self::Error>> + Send
where Self: Sync,

Convenience method for single-tenant resource creation. Read more
Source§

fn get_single_tenant( &self, resource_type: &str, id: &str, request_id: Option<String>, ) -> impl Future<Output = Result<Option<VersionedResource>, Self::Error>> + Send
where Self: Sync,

Convenience method for single-tenant resource retrieval.
Source§

fn update_single_tenant( &self, resource_type: &str, id: &str, data: Value, expected_version: Option<&RawVersion>, request_id: Option<String>, ) -> impl Future<Output = Result<VersionedResource, Self::Error>> + Send
where Self: Sync,

Convenience method for single-tenant resource update.
Source§

fn delete_single_tenant( &self, resource_type: &str, id: &str, expected_version: Option<&RawVersion>, request_id: Option<String>, ) -> impl Future<Output = Result<(), Self::Error>> + Send
where Self: Sync,

Convenience method for single-tenant resource deletion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ScimValidator for T

Source§

fn is_valid_scim_path(&self, path: &str) -> bool

Validate if a path represents a valid SCIM attribute. Read more
Source§

fn is_valid_complex_path(&self, path: &str) -> bool

Validate a complex SCIM path (containing dots). Read more
Source§

fn is_valid_simple_path(&self, attribute: &str) -> bool

Validate a simple SCIM path (single attribute name). Read more
Source§

fn is_multivalued_attribute(&self, attribute_name: &str) -> bool

Check if an attribute is multi-valued according to SCIM specifications. Read more
Source§

fn is_readonly_attribute(&self, path: &str) -> bool

Check if an attribute path refers to a readonly attribute. Read more
Source§

fn is_valid_username(&self, username: &str) -> bool

Validate that a username meets SCIM requirements. Read more
Source§

fn is_valid_external_id(&self, external_id: &str) -> bool

Validate an external ID format. Read more
Source§

fn is_valid_schema_uri(&self, schema_uri: &str) -> bool

Check if a schema URI is valid for SCIM. Read more
Source§

fn extract_base_attribute<'a>(&self, path: &'a str) -> &'a str

Extract the attribute name from a potentially complex path. Read more
Source§

impl<T> TenantValidator for T

Source§

fn validate_tenant_context( &self, expected_tenant_id: &str, context: &RequestContext, ) -> Result<(), String>

Validate that the context has the expected tenant.
Source§

fn validate_single_tenant_context( &self, context: &RequestContext, ) -> Result<(), String>

Validate that the context is for single-tenant operation.
Source§

fn require_tenant_context(&self, context: &RequestContext) -> Result<(), String>

Extract tenant context or return error for multi-tenant operations.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<P> ToSingleTenant<P> for P

Source§

fn to_single_tenant(self) -> TenantValidatingProvider<P>

Convert to a provider that validates single-tenant contexts.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,