public void PolicyName_YieldsPolicyNameInRule() { var group = FieldSecurityGroup.FromAttributeCollection(typeof(PolicyNameObject)); Assert.IsNotNull(group); Assert.AreEqual(1, group.Count); Assert.IsFalse(group.AllowAnonymous); var policy = group.First(); Assert.AreEqual("TestPolicy", policy.PolicyName); Assert.IsEmpty(policy.AllowedRoles); }
public void RolePolicyCombined_YieldsSingleRule() { var group = FieldSecurityGroup.FromAttributeCollection(typeof(PolicyNameWithRolesObject)); Assert.IsNotNull(group); Assert.AreEqual(1, group.Count); Assert.IsFalse(group.AllowAnonymous); var policy = group.First(); Assert.AreEqual("TestPolicWithRoleList", policy.PolicyName); Assert.AreEqual(2, policy.AllowedRoles.Count); Assert.IsTrue(policy.AllowedRoles.Contains("roleQ")); Assert.IsTrue(policy.AllowedRoles.Contains("roleW")); }
public void Roles_YieldsRoleInRule() { var group = FieldSecurityGroup.FromAttributeCollection(typeof(RoleListObject)); Assert.IsNotNull(group); Assert.AreEqual(1, group.Count); Assert.IsFalse(group.AllowAnonymous); var policy = group.First(); Assert.AreEqual(null, policy.PolicyName); Assert.AreEqual(3, policy.AllowedRoles.Count); Assert.IsTrue(policy.AllowedRoles.Contains("role1")); Assert.IsTrue(policy.AllowedRoles.Contains("role2")); Assert.IsTrue(policy.AllowedRoles.Contains("role3")); }
public void MultiPolicy_HasAnonymousAttribute_IndicatesAll() { var group = FieldSecurityGroup.FromAttributeCollection(typeof(PolicyNameWithAnonymousObject)); Assert.IsNotNull(group); Assert.AreEqual(2, group.Count); Assert.IsTrue(group.AllowAnonymous); var policy = group.First(); Assert.AreEqual("TestPolicyWithAnonSupport", policy.PolicyName); Assert.AreEqual(0, policy.AllowedRoles.Count); var rolePolicy = group.Skip(1).First(); Assert.AreEqual(3, rolePolicy.AllowedRoles.Count); Assert.IsTrue(rolePolicy.AllowedRoles.Contains("roleA")); Assert.IsTrue(rolePolicy.AllowedRoles.Contains("roleB")); Assert.IsTrue(rolePolicy.AllowedRoles.Contains("roleC")); }
/// <summary> /// When overridden in a child class this method builds out the template according to its own individual requirements. /// </summary> protected override void ParseTemplateDefinition() { _fieldDeclaration = this.SingleAttributeOfTypeOrDefault <GraphFieldAttribute>(); // ------------------------------------ // Common Metadata // ------------------------------------ this.Route = this.GenerateFieldPath(); this.Mode = _fieldDeclaration?.ExecutionMode ?? FieldResolutionMode.PerSourceItem; this.Complexity = _fieldDeclaration?.Complexity; this.Description = this.SingleAttributeOfTypeOrDefault <DescriptionAttribute>()?.Description; var depreciated = this.SingleAttributeOfTypeOrDefault <DeprecatedAttribute>(); if (depreciated != null) { this.IsDeprecated = true; this.DeprecationReason = depreciated.Reason?.Trim(); } var objectType = GraphValidation.EliminateWrappersFromCoreType(this.DeclaredReturnType); var typeExpression = GraphValidation.GenerateTypeExpression(this.DeclaredReturnType, this); typeExpression = typeExpression.CloneTo(GraphTypeNames.ParseName(objectType, this.Parent.Kind)); // ------------------------------------ // Gather Possible Types and/or union definition // ------------------------------------ this.BuildUnionProxyInstance(); if (this.UnionProxy != null) { this.PossibleTypes = new List <Type>(this.UnionProxy.Types); } else { this.PossibleTypes = new List <Type>(); // the possible types attribte is optional but expects taht the concrete types are added // to the schema else where lest a runtime exception occurs of a missing graph type. var typesAttrib = this.SingleAttributeOfTypeOrDefault <PossibleTypesAttribute>(); if (typesAttrib != null) { foreach (var type in typesAttrib.PossibleTypes) { this.PossibleTypes.Add(type); } } // add any types decalred on the primary field declaration if (_fieldDeclaration != null) { foreach (var type in _fieldDeclaration.Types) { var strippedType = GraphValidation.EliminateWrappersFromCoreType(type); if (strippedType != null) { this.PossibleTypes.Add(strippedType); } } } if (objectType != null && !Validation.IsCastable <IGraphActionResult>(objectType) && GraphValidation.IsValidGraphType(objectType)) { this.PossibleTypes.Insert(0, objectType); } } this.PossibleTypes = this.PossibleTypes.Distinct().ToList(); // ------------------------------------ // Adjust the action result to the actual return type this field returns // ------------------------------------ if (Validation.IsCastable <IGraphActionResult>(objectType)) { if (this.UnionProxy != null) { // if a union was decalred preserve whatever modifer elements // were decalred but alter the return type to object (a known common element among all members of the union) objectType = typeof(object); } else if (_fieldDeclaration != null && _fieldDeclaration.Types.Count > 0) { objectType = _fieldDeclaration.Types[0]; typeExpression = GraphValidation.GenerateTypeExpression(objectType, this) .CloneTo(GraphTypeNames.ParseName(objectType, this.Parent.Kind)); objectType = GraphValidation.EliminateWrappersFromCoreType(objectType); } else if (this.PossibleTypes.Count > 0) { objectType = this.PossibleTypes[0]; typeExpression = GraphValidation.GenerateTypeExpression(objectType, this) .CloneTo(GraphTypeNames.ParseName(objectType, this.Parent.Kind)); objectType = GraphValidation.EliminateWrappersFromCoreType(objectType); } else { objectType = typeof(object); } } this.ObjectType = objectType; if (this.UnionProxy != null) { this.TypeExpression = typeExpression.CloneTo(this.UnionProxy.Name); } else { this.TypeExpression = typeExpression; } // ------------------------------------ // Async Requirements // ------------------------------------ this.IsAsyncField = Validation.IsCastable <Task>(this.DeclaredReturnType); // ------------------------------------ // Security Policies // ------------------------------------ _securityPolicies = FieldSecurityGroup.FromAttributeCollection(this.AttributeProvider); }
/// <summary> /// When overridden in a child class this method builds out the template according to its own individual requirements. /// </summary> protected override void ParseTemplateDefinition() { base.ParseTemplateDefinition(); // ------------------------------------ // Common Metadata // ------------------------------------ this.Route = this.GenerateFieldPath(); this.Description = this.SingleAttributeOfTypeOrDefault <DescriptionAttribute>()?.Description; // ------------------------------------ // Security Policies // ------------------------------------ _securityPolicies = FieldSecurityGroup.FromAttributeCollection(this.AttributeProvider); // ------------------------------------ // Parse the methods on this type for fields to include in the graph // ------------------------------------ var parsedItems = new List <IGraphTypeFieldTemplate>(); var templateMembers = this.ObjectType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(x => !x.IsAbstract && !x.IsGenericMethod && !x.IsSpecialName).Cast <MemberInfo>() .Concat(this.ObjectType.GetProperties(BindingFlags.Public | BindingFlags.Instance)); foreach (var member in templateMembers) { if (this.CouldBeGraphField(member)) { // All members on types are "query operations" but are shown as part of the '[type]' collection // kinda wierd when put against controllers which declare against [Query] and [Mutation] but are also types. var parsedTemplate = this.CreateFieldTemplate(member); parsedTemplate?.Parse(); if (parsedTemplate?.Route == null || !this.AllowedGraphCollectionTypes.Contains(parsedTemplate.Route.RootCollection)) { _invalidFields = _invalidFields ?? new List <IGraphTypeFieldTemplate>(); _invalidFields.Add(parsedTemplate); } else { parsedItems.Add(parsedTemplate); } } } // ensure no overloaded methods that are to be mapped onto the graph cause naming collisions // on the object graph with other methods or properties. _duplicateNames = parsedItems.Select(x => x.Route.Path) .GroupBy(x => x) .Where(x => x.Count() > 1) .Select(x => x.Key); foreach (var field in parsedItems.Where(x => !_duplicateNames.Contains(x.Route.Path))) { _fields.Add(field.Route.Path, field); } // ------------------------------------ // Pull a reference to any interfaces declared by this type for later inclusion in the object graph meta data. // ------------------------------------ foreach (var iface in this.ObjectType.GetInterfaces().Where(x => x.IsPublic)) { _interfaces.Add(iface); } }