/// <summary> /// Indicates if a schema element is currently visible. /// </summary> /// <param name="configuration"> /// A domain configuration. /// </param> /// <param name="context"> /// An optional invocation context. /// </param> /// <param name="model"> /// A model. /// </param> /// <param name="element"> /// A schema element. /// </param> /// <returns> /// <c>true</c> if the element is currently /// visible; otherwise, <c>false</c>. /// </returns> public bool IsVisible( DomainConfiguration configuration, InvocationContext context, IEdmModel model, IEdmSchemaElement element) { Ensure.NotNull(element); // TODO GitHubIssue#34 : Filter out proper visible types if (element is IEdmType || element is IEdmOperation) { return true; } return this.IsVisible( configuration, context, element.Namespace, element.Name); }
/// <inheritdoc/> public Task<IEdmModel> GetModelAsync(InvocationContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, "context"); var model = new EdmModel(); var apiContext = context.ApiContext; var dbContext = apiContext.GetProperty<DbContext>(DbApiConstants.DbContextKey); var elementMap = new Dictionary<MetadataItem, IEdmElement>(); var efModel = (dbContext as IObjectContextAdapter) .ObjectContext.MetadataWorkspace; var namespaceName = efModel.GetItems<EntityType>(DataSpace.CSpace) .Select(t => efModel.GetObjectSpaceType(t).NamespaceName) .GroupBy(nameSpace => nameSpace) .Select(group => new { NameSpace = group.Key, Count = group.Count(), }) .OrderByDescending(nsItem => nsItem.Count) .Select(nsItem => nsItem.NameSpace) .FirstOrDefault(); if (namespaceName == null) { // When dbContext has not a namespace, just use its type name as namespace. namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name; } var efEntityContainer = efModel.GetItems<EntityContainer>(DataSpace.CSpace).Single(); var entityContainer = new EdmEntityContainer(namespaceName, efEntityContainer.Name); elementMap.Add(efEntityContainer, entityContainer); // TODO GitHubIssue#36 : support complex and enumeration types foreach (var efEntitySet in efEntityContainer.EntitySets) { var efEntityType = efEntitySet.ElementType; if (elementMap.ContainsKey(efEntityType)) { continue; } List<EdmStructuralProperty> concurrencyProperties; var entityType = CreateEntityType(efModel, efEntityType, model, elementMap, out concurrencyProperties); model.AddElement(entityType); elementMap.Add(efEntityType, entityType); var entitySet = entityContainer.AddEntitySet(efEntitySet.Name, entityType); if (concurrencyProperties != null) { model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties); } elementMap.Add(efEntitySet, entitySet); } foreach (var efAssociationSet in efEntityContainer.AssociationSets) { AddNavigationProperties(efAssociationSet, elementMap); AddNavigationPropertyBindings(efAssociationSet, elementMap); } // TODO GitHubIssue#36 : support function imports model.AddElement(entityContainer); return Task.FromResult<IEdmModel>(model); }
/// <summary> /// Asynchronously produces a base model. /// </summary> /// <param name="context"> /// The model context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is the base model. /// </returns> public Task<IEdmModel> GetModelAsync( InvocationContext context, CancellationToken cancellationToken) { var model = new EdmModel(); var domainContext = context.ApiContext; var dbContext = domainContext.GetProperty<DbContext>(DbApiConstants.DbContextKey); var elementMap = new Dictionary<IAnnotatable, IEdmElement>(); var efModel = dbContext.Model; var namespaceName = efModel.EntityTypes .Select(t => t.HasClrType() ? t.ClrType.Namespace : null) .Where(t => t != null) .GroupBy(nameSpace => nameSpace) .Select(group => new { NameSpace = group.Key, Count = group.Count(), }) .OrderByDescending(nsItem => nsItem.Count) .Select(nsItem => nsItem.NameSpace) .FirstOrDefault(); if (namespaceName == null) { // When dbContext has not a namespace, just use its type name as namespace. namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name; } var entityTypes = efModel.EntityTypes; var entityContainer = new EdmEntityContainer( namespaceName, "Container"); var dbSetProperties = dbContext.GetType(). GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance). Where(e => e.PropertyType.IsGenericType && e.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)). ToDictionary(e => e.PropertyType.GetGenericArguments()[0]); // TODO GitHubIssue#36 : support complex and entity inheritance foreach (var efEntityType in entityTypes) { if (elementMap.ContainsKey(efEntityType)) { continue; } List<EdmStructuralProperty> concurrencyProperties; var entityType = ModelProducer.CreateEntityType( efModel, efEntityType, model, out concurrencyProperties); model.AddElement(entityType); elementMap.Add(efEntityType, entityType); System.Reflection.PropertyInfo propInfo; if (dbSetProperties.TryGetValue(efEntityType.ClrType, out propInfo)) { var entitySet = entityContainer.AddEntitySet(propInfo.Name, entityType); if (concurrencyProperties != null) { model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties); } } } foreach (var efEntityType in entityTypes) { foreach (var navi in efEntityType.GetNavigations()) { ModelProducer.AddNavigationProperties( efModel, navi, model, elementMap); ModelProducer.AddNavigationPropertyBindings( efModel, navi, entityContainer, elementMap); } } // TODO GitHubIssue#36 : support function imports model.AddElement(entityContainer); return Task.FromResult<IEdmModel>(model); }
/// <summary> /// Deactivates this API policy. /// </summary> /// <param name="context"> /// An invocation context. /// </param> public void Deactivate(InvocationContext context) { context.RevokeRole(this.Role); }
/// <summary> /// Activates this API policy. /// </summary> /// <param name="context"> /// An invocation context. /// </param> public void Activate(InvocationContext context) { context.AssertRole(this.Role); }
public Task<IEdmModel> GetModelAsync(InvocationContext context, CancellationToken cancellationToken) { var builder = new ODataConventionModelBuilder(); builder.EntityType<Person>(); return Task.FromResult(builder.GetEdmModel()); }
public Task<IEdmModel> GetModelAsync(InvocationContext context, CancellationToken cancellationToken) { return Task.FromResult<IEdmModel>(model); }
private bool IsVisible( DomainConfiguration configuration, InvocationContext context, string namespaceName, string securableName) { List<string> assertedRoles = null; if (context != null) { assertedRoles = context.GetProperty<List<string>>(AssertedRoles); } var permissions = configuration.GetProperty<IEnumerable<DomainPermission>>(Permissions); if (permissions == null) { return false; } permissions = permissions.Where(p => ( p.PermissionType == DomainPermissionType.All || p.PermissionType == DomainPermissionType.Inspect) && ( (p.NamespaceName == null && p.SecurableName == null) || (p.NamespaceName == namespaceName && p.SecurableName == securableName)) && p.ChildName == null && (p.Role == null || this.IsInRole(p.Role) || (assertedRoles != null && assertedRoles.Contains(p.Role)))); if (!permissions.Any() || permissions.Any(p => p.IsDeny)) { return false; } return true; }
/// <summary> /// Indicates if an entity container element is currently visible. /// </summary> /// <param name="configuration"> /// A domain configuration. /// </param> /// <param name="context"> /// An optional invocation context. /// </param> /// <param name="model"> /// A model. /// </param> /// <param name="element"> /// An entity container element. /// </param> /// <returns> /// <c>true</c> if the element is currently /// visible; otherwise, <c>false</c>. /// </returns> public bool IsVisible( DomainConfiguration configuration, InvocationContext context, IEdmModel model, IEdmEntityContainerElement element) { Ensure.NotNull(element); return this.IsVisible( configuration, context, null, element.Name); }