async public static Task <HandlerInstance> GetHandlerInstance(this IServiceProvider serviceProvider, HandlerInfo handlerInfo)
        {
            var handlerInstance = new HandlerInstance
            {
                Method   = handlerInfo.Method,
                Instance = serviceProvider.GetService(handlerInfo.HandlerType)
            };

            if (handlerInstance.Instance is null)
            {
                throw new SWException($"Could not find required service {handlerInfo.Key} for resource {handlerInfo.Resource}.");
            }

            CqApiOptions options            = serviceProvider.GetService <CqApiOptions>() ?? new CqApiOptions();
            var          protectAttribute   = handlerInfo.HandlerType.GetCustomAttribute <ProtectAttribute>();
            var          unprotectAttribute = handlerInfo.HandlerType.GetCustomAttribute <UnprotectAttribute>();

            if ((options.ProtectAll && unprotectAttribute == null) || protectAttribute is ProtectAttribute)
            {
                var requestContext = serviceProvider.GetRequiredService <RequestContext>();

                if (!requestContext.IsValid)
                {
                    throw new SWUnauthorizedException();
                }

                if (protectAttribute?.RequireRole ?? false)
                {
                    var prefix = string.IsNullOrWhiteSpace(options.RolePrefix) ? handlerInfo.Resource : $"{options.RolePrefix}.{handlerInfo.Resource}";

                    var requiredRoles = new string[]
                    {
                        $"{prefix}.{handlerInfo.HandlerType.Name}",
                        $"{prefix}.*"
                    };

                    if (!requestContext.User.Claims.Any(c => c.Subject.RoleClaimType == ClaimTypes.Role && requiredRoles.Contains(c.Value, StringComparer.OrdinalIgnoreCase)))
                    {
                        throw new SWForbiddenException();
                    }
                }
            }

            return(handlerInstance);
        }
        public static IServiceCollection AddCqApi(this IServiceCollection services, Action <CqApiOptions> configure, params Assembly[] assemblies)
        {
            var cqApiOptions = new CqApiOptions();

            if (configure != null)
            {
                configure.Invoke(cqApiOptions);
            }
            services.AddSingleton(cqApiOptions);

            services.AddSingleton <ServiceDiscovery>();

            if (assemblies.Length == 0)
            {
                assemblies = new Assembly[] { Assembly.GetCallingAssembly() }
            }
            ;

            services.Scan(scan => scan
                          .FromAssemblies(assemblies)
                          .AddClasses(classes => classes.AssignableTo <IHandler>())
                          .AsSelf().As <IHandler>().WithScopedLifetime());

            services.Scan(scan => scan
                          .FromAssemblies(assemblies)
                          .AddClasses(classes => classes.AssignableTo <IValidator>())
                          .AsImplementedInterfaces().WithTransientLifetime());

            services.AddHttpContextAccessor();
            services.AddScoped <RequestContext>();
            services.AddRouting(options =>
            {
                options.ConstraintMap.Add("cqapiPrefix", typeof(CqapiPrefixRouteConstraint));
            });

            return(services);
        }
    }
Exemple #3
0
        public ServiceDiscovery(IServiceProvider serviceProvider, ILogger <ServiceDiscovery> logger, CqApiOptions options)
        {
            this.options = options;
            using (var scope = serviceProvider.CreateScope())
            {
                var registeredHandlers = scope.ServiceProvider.GetServices <IHandler>();

                foreach (var svc in registeredHandlers)
                {
                    var serviceType             = svc.GetType();
                    var interfaceType           = serviceType.GetTypeInfo().ImplementedInterfaces.Where(i => typeof(IHandler).IsAssignableFrom(i) && i != typeof(IHandler)).Single();
                    var interfaceTypeNormalized = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;

                    var typeNameArray = serviceType.FullName.Split('.');
                    var resourceName  = typeNameArray[typeNameArray.Length - 2].ToLower();

                    var handlerNameAttribute = serviceType.GetCustomAttribute <HandlerNameAttribute>();
                    var handlerName          = handlerNameAttribute == null ? "" : $"/{handlerNameAttribute.Name.ToLower()}";

                    if (!resourceHandlers.ContainsKey(resourceName))
                    {
                        resourceHandlers.Add(resourceName, new Dictionary <string, HandlerInfo>(StringComparer.OrdinalIgnoreCase));
                    }

                    var handlerKey = $"{HandlerTypeMetadata.Handlers[interfaceTypeNormalized].Key}{handlerName}";

                    resourceHandlers[resourceName][handlerKey] = new HandlerInfo
                    {
                        HandlerType             = serviceType,
                        Method                  = interfaceType.GetMethod("Handle"),
                        ArgumentTypes           = interfaceType.GetMethod("Handle").GetParameters().Select(p => p.ParameterType).ToList(),
                        Key                     = handlerKey,
                        Resource                = resourceName,
                        NormalizedInterfaceType = interfaceTypeNormalized
                    };
                }
            }
        }
Exemple #4
0
 public CqapiPrefixRouteConstraint(CqApiOptions options)
 {
     this.options = options;
 }