/// <summary> /// Parses the <paramref name="uri"/> as a reference to a local resource. /// Returns null if the specified <paramref name="uri"/> is invalid. /// </summary> /// <param name="uri">The URI.</param> /// <param name="serverConfiguration">The server configuration.</param> /// <returns>ScimResourceReference.</returns> public static ScimResourceReference ToScimResourceReference(this Uri uri, ScimServerConfiguration serverConfiguration) { var scimPathBase = AmbientRequestService.BasePath; var uriPaths = (string.IsNullOrWhiteSpace(scimPathBase) ? uri.AbsolutePath : uri.AbsolutePath.Replace(scimPathBase, "")) .TrimStart('/') .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (uriPaths.Length < 2) { return(null); } var resourceEndpoint = uriPaths[0]; var resourceId = uriPaths[1]; var resourceDefinition = serverConfiguration .GetResourceTypeDefinitions(AmbientRequestService.ProtocolVersion) .SingleOrDefault(rtd => rtd.Endpoint.IndexOf(resourceEndpoint, StringComparison.OrdinalIgnoreCase) >= 0); if (resourceDefinition == null) { return(null); // invalid uri } return(new ScimResourceReference(resourceDefinition, resourceId)); }
/// <summary> /// Parses the <paramref name="uri"/> as a reference to a local resource. /// Returns null if the specified <paramref name="uri"/> is invalid. /// </summary> /// <param name="uri">The URI.</param> /// <param name="serverConfiguration">The server configuration.</param> /// <returns>ScimResourceReference.</returns> public static ScimResourceReference ToScimResourceReference(this Uri uri, ScimServerConfiguration serverConfiguration) { var scimPathBase = AmbientRequestService.BasePath; var uriPaths = (string.IsNullOrWhiteSpace(scimPathBase) ? uri.AbsolutePath : uri.AbsolutePath.Replace(scimPathBase, "")) .TrimStart('/') .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (uriPaths.Length < 2) return null; var resourceEndpoint = uriPaths[0]; var resourceId = uriPaths[1]; var resourceDefinition = serverConfiguration .GetResourceTypeDefinitions(AmbientRequestService.ProtocolVersion) .SingleOrDefault(rtd => rtd.Endpoint.IndexOf(resourceEndpoint, StringComparison.OrdinalIgnoreCase) >= 0); if (resourceDefinition == null) return null; // invalid uri return new ScimResourceReference(resourceDefinition, resourceId); }
public static Uri EnforceScimUri(Uri uri, IScimTypeAttributeDefinition attributeDefinition, ScimServerConfiguration serverConfiguration) { /* * SCIM 2.0 Specification * referenceTypes A multi-valued array of JSON strings that indicate * the SCIM resource types that may be referenced. Valid values * are as follows: * + A SCIM resource type (e.g., "User" or "Group"), + + "external" - indicating that the resource is an external + resource (e.g., a photo), or + + "uri" - indicating that the reference is to a service + endpoint or an identifier (e.g., a schema URN). */ if (attributeDefinition.ReferenceTypes != null && attributeDefinition.ReferenceTypes.Any()) { IScimResourceTypeDefinition resourceDefinition = null; foreach (var referenceType in attributeDefinition.ReferenceTypes) { if (referenceType.Equals(ScimConstants.ReferenceTypes.External, StringComparison.OrdinalIgnoreCase)) { // do not accept relative URIs for an attribute which is defined as an external reference type if (!uri.IsAbsoluteUri) { continue; } return(uri); } if (referenceType.Equals(ScimConstants.ReferenceTypes.Uri, StringComparison.OrdinalIgnoreCase)) { if (uri.ToString().StartsWith(ScimConstants.Defaults.URNPrefix, StringComparison.OrdinalIgnoreCase)) { return(uri); // uri is an identifier, possibly schema } // uri MUST be a valid SCIM resource resourceDefinition = serverConfiguration .GetResourceTypeDefinitions(AmbientRequestService.ProtocolVersion) .SingleOrDefault(rtd => uri.AbsolutePath.IndexOf(rtd.Endpoint, StringComparison.OrdinalIgnoreCase) >= 0); if (resourceDefinition != null) { break; } continue; } // uri MUST be a valid SCIM resource that's within the allowed referenceTypes resourceDefinition = serverConfiguration .GetResourceTypeDefinitions(AmbientRequestService.ProtocolVersion) .SingleOrDefault( rtd => rtd.Name.Equals(referenceType, StringComparison.OrdinalIgnoreCase) && uri.AbsolutePath.IndexOf(rtd.Endpoint, StringComparison.OrdinalIgnoreCase) >= 0); if (resourceDefinition != null) { break; } } // invalid URI for the associated reference types if (resourceDefinition == null) { return(uri); // allow validation to handle invalid uri's } return(BuildScimUri(uri)); } /* * Relative URIs should be resolved as specified in * Section 5.2 of [RFC3986]. However, the base URI for relative URI * resolution MUST include all URI components and path segments up to, * but not including, the Endpoint URI (the SCIM service provider root * endpoint) */ return(BuildScimUri(uri)); }