Пример #1
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
                    };
                }
            }
        }
Пример #2
0
        async Task <IActionResult> ExecuteHandler(HandlerInfo handlerInfo, string key, object body = null, bool lookup = false)
        {
            var handlerInstance = await serviceProvider.GetHandlerInstance(handlerInfo);

            if (handlerInfo.NormalizedInterfaceType == typeof(ISearchyHandler))
            {
                var searchyRequest = new SearchyRequest(Request.QueryString.Value);
                var result         = await handlerInstance.Invoke(searchyRequest, lookup, null);

                if (lookup)
                {
                    return(StatusCode(206, result));
                }
                return(Ok(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(IQueryHandler))
            {
                var result = await handlerInstance.Invoke();

                return(Ok(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(IQueryHandler <>))
            {
                var request = Request.Query.GetInstance(handlerInfo.ArgumentTypes[0]);
                var result  = await handlerInstance.Invoke(request);

                return(Ok(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(IQueryHandler <,>))
            {
                object keyParam;
                try
                {
                    keyParam = key.ConvertValueToType(handlerInfo.ArgumentTypes[0]);
                }
                catch (Exception ex)
                {
                    throw new BadInputFormatException(ex);
                }
                var request = Request.Query.GetInstance(handlerInfo.ArgumentTypes[1]);
                var result  = await handlerInstance.Invoke(keyParam, request);

                return(Ok(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(ICommandHandler))
            {
                var result = await handlerInstance.Invoke();

                return(HandleResult(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(ICommandHandler <>))
            {
                object typedParam;
                try
                {
                    typedParam = JsonConvert.DeserializeObject(body.ToString(), handlerInfo.ArgumentTypes[0]);
                }
                catch (Exception ex)
                {
                    throw new BadInputFormatException(ex);
                }
                if (!await ValidateInput(typedParam))
                {
                    return(BadRequest(ModelState));
                }
                var result = await handlerInstance.Invoke(typedParam);

                return(HandleResult(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(ICommandHandler <,>))
            {
                object typedParam;
                object keyParam;
                try
                {
                    keyParam   = key.ConvertValueToType(handlerInfo.ArgumentTypes[0]);
                    typedParam = JsonConvert.DeserializeObject(body.ToString(), handlerInfo.ArgumentTypes[1]);
                }
                catch (Exception ex)
                {
                    throw new BadInputFormatException(ex);
                }

                if (!await ValidateInput(typedParam))
                {
                    return(BadRequest(ModelState));
                }
                var result = await handlerInstance.Invoke(keyParam, typedParam);

                return(HandleResult(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(IGetHandler <>))
            {
                object keyParam;
                try
                {
                    keyParam = key.ConvertValueToType(handlerInfo.ArgumentTypes[0]);
                }
                catch (Exception ex)
                {
                    throw new BadInputFormatException(ex);
                }
                var result = await handlerInstance.Invoke(keyParam, lookup);

                if (result == null)
                {
                    return(NotFound());
                }
                if (lookup)
                {
                    return(StatusCode(206, result));
                }
                return(HandleResult(result));
            }
            else if (handlerInfo.NormalizedInterfaceType == typeof(IDeleteHandler <>))
            {
                object keyParam;
                try
                {
                    keyParam = key.ConvertValueToType(handlerInfo.ArgumentTypes[0]);
                }
                catch (Exception ex)
                {
                    throw new BadInputFormatException(ex);
                }
                var result = await handlerInstance.Invoke(keyParam);

                return(Accepted());
            }
            else
            {
                return(NotFound());
            }
        }
Пример #3
0
        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);
        }