private bool ShouldIncludeInQueryCriteria(PropertyDescriptor property, object value, TEntity entity) { // Null values and underscore-prefixed properties are ignored for specification purposes if (value == null || property.Name.StartsWith("_") || "|Url|".Contains(property.Name)) { // TODO: Come up with better way to exclude non-data properties return(false); } Type valueType = value.GetType(); // Only use value types (or strings), and non-default values (i.e. ignore 0's) var result = (valueType.IsValueType || valueType == typeof(string)) && (!value.Equals(valueType.GetDefaultValue()) || UniqueIdSpecification.IsUSI(property.Name) && GetPropertyValue(entity, UniqueIdSpecification.GetUniqueIdPropertyName(property.Name)) != null); // Don't include properties that are explicitly to be ignored result = result && !_propertiesToIgnore.Contains(property.Name); // Don't include UniqueId properties when they appear on a Person entity result = result && (!_uniqueIdProperties.Contains(property.Name) || PersonEntitySpecification.IsPersonEntity(entity.GetType())); return(result); }
public virtual ICollection <ValidationResult> ValidateObject(object @object) { var validationResults = new List <ValidationResult>(); var objType = @object.GetType(); if (PersonEntitySpecification.IsPersonEntity(objType)) { var objectWithIdentifier = (IHasIdentifier)@object; var persistedUniqueId = _personIdentifiersCache.GetUniqueId(objType.Name, objectWithIdentifier.Id); var objectWithUniqueId = (IIdentifiablePerson)@object; string newUniqueId = objectWithUniqueId.UniqueId; if (persistedUniqueId != null && persistedUniqueId != newUniqueId) { validationResults.Add(new ValidationResult("A person's UniqueId cannot be modified.")); } } if (validationResults.Any()) { SetInvalid(); } else { SetValid(); } return(validationResults); }
public Task ExecuteAsync(TContext context, TResult result, CancellationToken cancellationToken) { if (!PersonEntitySpecification.IsPersonEntity(typeof(TResourceModel))) { return(Task.CompletedTask); } var entityWithId = context.PersistentModel as IHasIdentifier; if (entityWithId == null || entityWithId.Id != default(Guid)) { return(Task.CompletedTask); } var uniqueId = ((IIdentifiablePerson)context.Resource).UniqueId; var id = _personUniqueIdToIdCache.GetId(typeof(TResourceModel).Name, uniqueId); entityWithId.Id = id; // Mark identifier as being system supplied var entityWithIdSource = context.PersistentModel as IHasIdentifierSource; entityWithIdSource.IdSource = IdentifierSource.SystemSupplied; return(Task.CompletedTask); }
private Task InitializePersonTypeValueMaps(IdentityValueMaps entry, string personType, string context) { // Validate Person type if (!PersonEntitySpecification.IsPersonEntity(personType)) { throw new ArgumentException( string.Format( "Invalid person type '{0}'. Valid person types are: {1}", personType, "'" + string.Join("','", PersonEntitySpecification.ValidPersonTypes) + "'")); } // In web application scenarios, copy pertinent context from HttpContext to CallContext if (HttpContextStorageTransfer != null) { HttpContextStorageTransfer.TransferContext(); } var task = InitializePersonTypeValueMapsAsync(entry, personType, context); if (task.Status == TaskStatus.Created) { task.Start(); } return(task); }
/// <summary> /// Gets the identifier values available for all members of the specified Person type as a streaming enumerable. /// </summary> /// <param name="personType">The type of person whose UniqueId is being requested (e.g. Student, Staff or Parent).</param> /// <returns>An enumerable collection of <see cref="PersonIdentifiersValueMap"/> instances containing the available identifiers /// for UniqueId and the corresponding Id and/or USI values (depending on the implementation).</returns> /// <remarks>Consumers should read all the data immediately because implementations should "stream" the /// data back for efficiency reasons, holding on resources such as a database connection until reading is /// complete. /// </remarks> public async Task <IEnumerable <PersonIdentifiersValueMap> > GetAllPersonIdentifiers(string personType) { Preconditions.ThrowIfNull(personType, nameof(personType)); // Validate Person type if (!PersonEntitySpecification.IsPersonEntity(personType)) { string validPersonTypes = string.Join("','", PersonEntitySpecification.ValidPersonTypes) .SingleQuoted(); throw new ArgumentException($"Invalid person type '{personType}'. Valid person types are: {validPersonTypes}"); } using (var session = _openStatelessSession()) { string aggregateNamespace = Namespaces.Entities.NHibernate.GetAggregateNamespace( personType, EdFiConventions.ProperCaseName); string entityName = $"{aggregateNamespace}.{personType}"; var criteria = session.CreateCriteria(entityName) .SetProjection( Projections.ProjectionList() .Add(Projections.Alias(Projections.Property($"{personType}USI"), "Usi")) .Add(Projections.Alias(Projections.Property($"{personType}UniqueId"), "UniqueId")) ) .SetResultTransformer(Transformers.AliasToBean <PersonIdentifiersValueMap>()); return(await criteria.ListAsync <PersonIdentifiersValueMap>()); } }
protected override void BuildAuthorizationSegments( AuthorizationBuilder <TContextData> authorizationBuilder, string[] authorizationContextPropertyNames) { authorizationContextPropertyNames .Where(pn => PersonEntitySpecification.IsPersonIdentifier(pn, "Student")) .ForEach(pn => authorizationBuilder.ClaimsMustBeAssociatedWith(pn, "ThroughEdOrgAssociation")); }
protected override void BuildAuthorizationSegments( AuthorizationBuilder <TContextData> authorizationBuilder, string[] authorizationContextPropertyNames) { authorizationBuilder.ClaimsMustBeAssociatedWith( authorizationContextPropertyNames .Where(p => PersonEntitySpecification.IsPersonIdentifier(p, "Student")) .ToArray()); }
public void Should_return_true_for_parent_entity() { AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonEntity( typeof(NHibernateEntities.ParentAggregate.EdFi.Parent)), Is.True), () => Assert.That( PersonEntitySpecification.IsPersonEntity( nameof(NHibernateEntities.ParentAggregate.EdFi.Parent)), Is.True) ); }
public void Should_return_true_for_parent_entity() { AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonEntity( typeof(Parent)), Is.True), () => Assert.That( PersonEntitySpecification.IsPersonEntity( nameof(Parent)), Is.True) ); }
public void Should_return_true_for_student_resource() { AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonEntity( typeof(Api.Common.Models.Resources.Student.EdFi.Student)), Is.True), () => Assert.That( PersonEntitySpecification.IsPersonEntity( nameof(Api.Common.Models.Resources.Student.EdFi.Student)), Is.True) ); }
public void Should_return_true_for_parent_resource() { AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonEntity( typeof(ModelResources.Parent.EdFi.Parent)), Is.True), () => Assert.That( PersonEntitySpecification.IsPersonEntity( nameof(ModelResources.Parent.EdFi.Parent)), Is.True) ); }
private string GetParentResource(Entity entity) { var resourceName = entity.Name; if (resourceName.EndsWith("type", StringComparison.InvariantCultureIgnoreCase)) { return("types"); } if (DescriptorEntitySpecification.IsEdFiDescriptorEntity(resourceName)) { return(ManagedDescriptorSpecification.IsEdFiManagedDescriptor(resourceName) ? "managedDescriptors" : "systemDescriptors"); } if (EducationOrganizationEntitySpecification.IsEducationOrganizationEntity(resourceName)) { return("educationOrganizations"); } if (PersonEntitySpecification.IsPersonEntity(resourceName)) { return("people"); } if (AssessmentSpecification.IsAssessmentEntity(resourceName)) { return("assessmentMetadata"); } if (resourceName.Equals("educationContent", StringComparison.InvariantCultureIgnoreCase)) { return(null); } if (EducationStandardSpecification.IsEducationStandardEntity(resourceName)) { return("educationStandards"); } if (PrimaryRelationshipEntitySpecification.IsPrimaryRelationshipEntity(resourceName)) { return("primaryRelationships"); } if (SurveySpecification.IsSurveyEntity(resourceName)) { return("surveyDomain"); } return("relationshipBasedData"); }
private static PropertyType GetBasePersonUniqueIdPropertyType(EntityProperty property) { //we need to go find the correct PropertyType information by looking through //the incoming associations for the ones that have the USI property //and walking those entities until we find the person type that is the base of this //property, then return the entity's unique id property's property type from there. return(GetNestedPersonEntityProperty(property, property.PropertyName) .Entity.Properties .Where(x => !UniqueIdSpecification.IsUSI(x.PropertyName) && PersonEntitySpecification.IsPersonIdentifier(x.PropertyName)) .Select(x => x.PropertyType) .Single()); }
public void Should_return_true_for_parent_Identifier_property() { AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonIdentifier( nameof(NHibernateEntities.ParentAggregate.EdFi.Parent.ParentUniqueId)), Is.True) ); AssertHelper.All( () => Assert.That( PersonEntitySpecification.IsPersonIdentifier( nameof(NHibernateEntities.ParentAggregate.EdFi.Parent.ParentUSI)), Is.True) ); }
private static string GetResourcePropertyName(EntityProperty property) { // Simplistic conversion using conventions if (property.IsLookup) { return(property.PropertyName.TrimSuffix("Id")); } // Convert USIs to UniqueIds everywhere but on the people if (UniqueIdSpecification.IsUSI(property.PropertyName) && !PersonEntitySpecification.IsPersonEntity(property.Entity.Name)) { return(property.PropertyName.Replace("USI", "UniqueId")); } return(property.PropertyName); }
private static EntityProperty GetNestedPersonEntityProperty(EntityProperty entityProperty, string entityPropertyName) { if (PersonEntitySpecification.IsPersonEntity(entityProperty.Entity.Name)) { return(entityProperty); } var interestingProperties = entityProperty.IncomingAssociations .Select( x => x.PropertyMappingByThisName[entityPropertyName] .OtherProperty) .ToList(); if (interestingProperties.None()) { return(null); } return(interestingProperties.Select(x => GetNestedPersonEntityProperty(x, x.PropertyName)) .FirstOrDefault(x => x != null)); }
private IEnumerable <PersonIdentifiersValueMap> GetPersonIdentifiersValueMap( string personType, string searchField, object searchValue) { // Validate Person type if (!PersonEntitySpecification.IsPersonEntity(personType)) { string validPersonTypes = string.Join("','", PersonEntitySpecification.ValidPersonTypes) .SingleQuoted(); throw new ArgumentException($"Invalid person type '{personType}'. Valid person types are: {validPersonTypes}"); } using (var session = _openStatelessSession()) { string aggregateNamespace = Namespaces.Entities.NHibernate.GetAggregateNamespace( personType, EdFiConventions.ProperCaseName); string entityName = $"{aggregateNamespace}.{personType}"; var criteria = session.CreateCriteria(entityName) .SetProjection( Projections.ProjectionList() .Add(Projections.Alias(Projections.Property($"{personType}USI"), "Usi")) .Add(Projections.Alias(Projections.Property($"{personType}UniqueId"), "UniqueId")) ); if (searchField != null) { criteria.Add(Expression.Eq($"{searchField}", searchValue)); } criteria.SetResultTransformer(Transformers.AliasToBean <PersonIdentifiersValueMap>()); return(criteria.List <PersonIdentifiersValueMap>()); } }
public ICollection <ValidationResult> ValidateObject(object @object) { var validationResults = new List <ValidationResult>(); var objType = @object.GetType(); if (!PersonEntitySpecification.IsPersonEntity(objType)) { SetValid(); return(new List <ValidationResult>()); } // All Person entities should have an Id property. var entityWithIdentifier = @object as IHasIdentifier; // This should never happen. if (entityWithIdentifier == null) { throw new NotImplementedException( string.Format( "Entity of type '{0}' representing a person did not implement the {1} interface to provide access to the GUID-based identifier. This implies an error in the implementation of the Person-type entity.", objType.FullName, typeof(IHasIdentifier).Name)); } // Used in conjunction with the PopulateIdFromUniqueIdOnPeople pipeline step, the Id // property should have already been populated if the UniqueId provided on the request // existed previously. // // For implementations with an integrated UniqueId system, it is an invalid request // if we are unable to resolve the UniqueId to a GUID-based Id by this point in the // processing of the request. if (entityWithIdentifier.Id == default(Guid)) { var person = @object as IIdentifiablePerson; // This should never happen. if (person == null) { throw new NotImplementedException( string.Format( "Entity of type '{0}' representing a person did not implement the {1} interface to provide access to the UniqueId value. This implies an error in the implementation of the Person-type entity.", objType.FullName, typeof(IIdentifiablePerson).Name)); } validationResults.Add( new ValidationResult( string.Format( "The supplied UniqueId value '{0}' was not resolved.", person.UniqueId))); } if (validationResults.Any()) { SetInvalid(); } else { SetValid(); } return(validationResults); }
private static bool IsDefiningUniqueId(ResourceClassBase resourceClass, ResourceProperty property) { return(UniqueIdSpecification.IsUniqueId(property.PropertyName) && PersonEntitySpecification.IsPersonEntity(resourceClass.Name)); }
private void ProcessQueryStringParameters(HqlBuilderContext builderContext, CompositeDefinitionProcessorContext processorContext) { // Get all non "special" query string parameter for property value equality processing var queryStringParameters = GetCriteriaQueryStringParameters(builderContext); foreach (var queryStringParameter in queryStringParameters) { ResourceProperty targetProperty; // TODO: Embedded convention. Types and descriptors at the top level if (processorContext.CurrentResourceClass.AllPropertyByName.TryGetValue(queryStringParameter.Key, out targetProperty)) { string criteriaPropertyName; object parameterValue; string personType; // Handle Lookup conversions if (targetProperty.IsLookup) { var id = _descriptorsCache.GetId( targetProperty.LookupTypeName, Convert.ToString(queryStringParameter.Value)); criteriaPropertyName = targetProperty.EntityProperty.PropertyName; parameterValue = id; } // Handle UniqueId conversions else if (UniqueIdSpecification.TryGetUniqueIdPersonType(targetProperty.PropertyName, out personType)) { int usi = _personUniqueIdToUsiCache.GetUsi(personType, Convert.ToString(queryStringParameter.Value)); // TODO: Embedded convention - Convert UniqueId to USI from Resource model to query Entity model on Person entities // The resource model maps uniqueIds to uniqueIds on the main entity(Student,Staff,Parent) if (PersonEntitySpecification.IsPersonEntity(targetProperty.ParentFullName.Name)) { criteriaPropertyName = targetProperty.EntityProperty.PropertyName.Replace("UniqueId", "USI"); } else { criteriaPropertyName = targetProperty.EntityProperty.PropertyName; } parameterValue = usi; } else { criteriaPropertyName = targetProperty.PropertyName; parameterValue = ConvertParameterValueForProperty(targetProperty, Convert.ToString(queryStringParameter.Value)); } // Add criteria to the query builderContext.SpecificationWhere.AppendFormat( "{0}{1}.{2} = :{2}", AndIfNeeded(builderContext.SpecificationWhere), builderContext.CurrentAlias, criteriaPropertyName); if (builderContext.CurrentQueryFilterParameterValueByName.ContainsKey(criteriaPropertyName)) { throw new ArgumentException( string.Format( "The value for parameter '{0}' was already assigned and cannot be reassigned using the query string.", criteriaPropertyName)); } builderContext.CurrentQueryFilterParameterValueByName[criteriaPropertyName] = parameterValue; } else { ThrowPropertyNotFoundException(queryStringParameter.Key); } } }
public static bool IsPersonEntity(this Entity entity) { return(PersonEntitySpecification.IsPersonEntity(entity.Name)); }
protected override object Build() { var resourceClassesToRender = ResourceModelProvider.GetResourceModel() .GetAllResources() .SelectMany( r => r.AllContainedItemTypesOrSelf.Where( i => TemplateContext.ShouldRenderResourceClass(i) // Don't render artifacts for base class children in the context of derived resources && !i.IsInheritedChildItem())) .OrderBy(r => r.Name) .ToList(); var entityInterfacesModel = new { EntitiesBaseNamespace = EdFiConventions.BuildNamespace( Namespaces.Entities.Common.BaseNamespace, TemplateContext.SchemaProperCaseName), Interfaces = resourceClassesToRender .Where(TemplateContext.ShouldRenderResourceClass) .Select( r => new { r.FullName.Schema, r.Name, AggregateName = r.Name, ImplementedInterfaces = GetImplementedInterfaceString(r), ParentInterfaceName = GetParentInterfaceName(r), ParentClassName = GetParentClassName(r), IdentifyingProperties = r .IdentifyingProperties // Exclude inherited identifying properties where the property has not been renamed .Where( p => !( p.EntityProperty ?.IsInheritedIdentifying == true && !p .EntityProperty ?.IsInheritedIdentifyingRenamed == true)) .OrderBy( p => p .PropertyName) .Select( p => new { p.IsServerAssigned, IsUniqueId = UniqueIdSpecification .IsUniqueId( p.PropertyName) && PersonEntitySpecification .IsPersonEntity( r.Name), p.IsLookup, CSharpType = p .PropertyType .ToCSharp( false), Name = p .PropertyName, CSharpSafePropertyName = p .PropertyName .MakeSafeForCSharpClass( r.Name), LookupName = p .PropertyName }) .ToList(), r.IsDerived, InheritedNonIdentifyingProperties = r.IsDerived ? r.AllProperties .Where(p => p.IsInherited && !p.IsIdentifying) .OrderBy(p => p.PropertyName) .Where(IsModelInterfaceProperty) .Select( p => new { p.IsLookup, CSharpType = p.PropertyType.ToCSharp(true), Name = p.PropertyName, LookupName = p.PropertyName.TrimSuffix("Id") }) .ToList() : null, NonIdentifyingProperties = r.NonIdentifyingProperties .Where(p => !p.IsInherited) .OrderBy(p => p.PropertyName) .Where(IsModelInterfaceProperty) .Select( p => new { p.IsLookup, CSharpType = p.PropertyType.ToCSharp(true), Name = p.PropertyName, CSharpSafePropertyName = p.PropertyName .MakeSafeForCSharpClass(r.Name), LookupName = p.PropertyName.TrimSuffix("Id") }) .ToList(), HasNavigableOneToOnes = r.EmbeddedObjects.Any(), NavigableOneToOnes = r .EmbeddedObjects .Where(eo => !eo.IsInherited) .OrderBy( eo => eo .PropertyName) .Select( eo => new { Name = eo .PropertyName }) .ToList(), InheritedLists = r.IsDerived ? r.Collections .Where(c => c.IsInherited) .OrderBy(c => c.PropertyName) .Select( c => new { c.ItemType.Name, PluralName = c.PropertyName }) .ToList() : null, Lists = r.Collections .Where(c => !c.IsInherited) .OrderBy(c => c.PropertyName) .Select( c => new { c.ItemType.Name, PluralName = c.PropertyName }) .ToList(), HasDiscriminator = r.HasDiscriminator(), AggregateReferences = r.Entity?.GetAssociationsToReferenceableAggregateRoots() .OrderBy(a => a.Name) .Select( a => new { AggregateReferenceName = a.Name, MappedReferenceDataHasDiscriminator = a.OtherEntity.HasDiscriminator() }) .ToList() }) .ToList() }; return(entityInterfacesModel); }