Exemplo n.º 1
0
        private ApiHandlerOutput Process(ApiInputHandler input)
        {
            string typeName = Business.Resource.GetType(input.Resource);

            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ApiNotFoundException(input.Resource);
            }

            bool canAccess = Business.Authorization.CanAccess(input.Resource, Context.Current.User);

            if (!canAccess)
            {
                logger.Warn($"Access denied for resource {input.Resource}");

                throw new SecurityException(Messages.AccessDenied);
            }

            if (Business.Authorization.RequireToken(input.Resource))
            {
                string token = input.Context.Request.Headers["ZestyApiToken"];

                if (string.IsNullOrWhiteSpace(token))
                {
                    token = input.Context.Request.Query["t"];
                }

                if (!Business.Authorization.IsValid(Context.Current.User.Id, input.Context.Session.Id, token))
                {
                    logger.Warn($"Invalid token for resource {input.Resource}");

                    throw new SecurityException(Messages.TokenMissing);
                }
            }

            ApiCacheItem cacheItem = ApiCache.Get(input);

            if (cacheItem != null)
            {
                logger.Info($"Output found in cache for request {input.Resource}");

                return(cacheItem.Output);
            }
            else
            {
                ApiHandlerBase handler = InstanceHelper.Create <ApiHandlerBase>(typeName);

                ApiHandlerOutput output = handler.Process(input);

                if (output.CachePolicy == ApiCachePolicy.Enable)
                {
                    cacheItem = new ApiCacheItem
                    {
                        Created  = DateTime.Now,
                        Output   = output,
                        Payload  = input.Body,
                        Resource = input.Resource
                    };

                    ApiCache.Store(cacheItem);

                    logger.Info($"Output stored in cache for request {input.Resource}");
                }


                if (output.ResourceHistoryOutput != null && output.ResourceHistoryOutput.ResourceHistoryPolicy == ApiResourceHistoryPolicy.Save)
                {
                    Business.History.Save(output.ResourceHistoryOutput.Item);
                }

                return(output);
            }
        }
Exemplo n.º 2
0
        public override ApiHandlerOutput Process(ApiInputHandler input)
        {
            Business.User.HardDelete(Guid.Parse(Get(input, "id")));

            return(GetOutput());
        }
Exemplo n.º 3
0
        public override ApiHandlerOutput Process(ApiInputHandler input)
        {
            UpdateResourceRequest request = GetEntity <UpdateResourceRequest>(input);

            Guid resourceId = Guid.Parse(request.Id);

            Guid domainId = Guid.Parse(request.Domain);

            using (SqlConnection connection = new SqlConnection(Settings.Current.StorageSource))
            {
                connection.Open();

                using (SqlCommand command = new SqlCommand("Zesty_Resource_Update", connection))
                {
                    command.CommandType = CommandType.StoredProcedure;

                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@resourceId", Value = resourceId
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@url", Value = request.Url.Trim()
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@ParentId", Value = !string.IsNullOrEmpty(request.ParentId) ? Guid.Parse(request.ParentId) : (Object)DBNull.Value
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@isPublic", Value = request.IsPublic ? 1 : 0
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@requireToken", Value = request.RequireToken ? 1 : 0
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@order", Value = request.Order
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@label", Value = !string.IsNullOrEmpty(request.Label) ? request.Label.Trim() : (Object)DBNull.Value
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@title", Value = !string.IsNullOrEmpty(request.Title) ? request.Title.Trim() : (Object)DBNull.Value
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@image", Value = !string.IsNullOrEmpty(request.Image) ? request.Image.Trim() : (Object)DBNull.Value
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@type", Value = !string.IsNullOrEmpty(request.Type) ? request.Type.Trim() : (Object)DBNull.Value
                    });
                    command.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@domain", Value = domainId
                    });

                    command.ExecuteNonQuery();
                }
            }

            return(GetOutput());
        }
Exemplo n.º 4
0
        public async Task Invoke(HttpContext context)
        {
            TimeKeeper timeKeeper = new TimeKeeper();

            string contentType = null;
            string content     = null;
            int    statusCode  = 200;

            try
            {
                LoadUser(context);

                string resourceName = context.Request.Path.Value;
                string body         = new StreamReader(context.Request.Body).ReadToEndAsync().Result;

                logger.Info($"User: {Context.Current.User?.Username}");
                logger.Info($"Resource: {resourceName}");
                logger.Debug($"Body: {body}");
                logger.Info($"Session ID: {context.Session.Id}");
                logger.Info($"HTTP method: {context.Request.Method}");

                ApiInputHandler input = new ApiInputHandler()
                {
                    Body     = body,
                    Context  = context,
                    Resource = resourceName
                };

                if (context.Request.Method == "OPTIONS")
                {
                    //TODO improve this poor code :D
                    contentType = ContentType.TextPlain;
                    content     = ":)";
                }
                else
                {
                    HandlerProcessor.Process(Settings.List("PreExecutionHandler"), context);

                    ApiHandlerOutput output = Process(input);

                    HandlerProcessor.Process(Settings.List("PostExecutionHandler"), context);

                    if (output.Type == ApiHandlerOutputType.JSon)
                    {
                        contentType = ContentType.ApplicationJson;
                        content     = JsonHelper.Serialize(output.Output);
                    }
                    else if (output.Type == ApiHandlerOutputType.TextAsJson)
                    {
                        contentType = ContentType.ApplicationJson;
                        content     = output.Output as string;
                    }
                    else if (output.Type == ApiHandlerOutputType.Text)
                    {
                        contentType = ContentType.TextPlain;
                        content     = output.Output as string;
                    }
                    else
                    {
                        throw new Exception(Messages.WrongApiOutput);
                    }
                }
            }

            #region catches

            catch (ApiInvalidArgumentException e)
            {
                logger.Error(e);

                statusCode  = 501;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (ApiNotFoundException e)
            {
                logger.Error(e);

                statusCode  = 404;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (ApiTokenExpiredException e)
            {
                logger.Error(e);

                statusCode  = 401;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (ApiAccessDeniedException e)
            {
                logger.Error(e);

                statusCode  = 401;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (MissingRequiredProperty e)
            {
                logger.Error(e);

                statusCode  = 400;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (CustomJsonException e)
            {
                logger.Error(e);

                statusCode  = 502; // TODO check this code
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (SecurityException e)
            {
                logger.Error(e);

                statusCode  = 403; // TODO check this code
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }
            catch (Exception e)
            {
                logger.Error(e);

                statusCode  = 500;
                contentType = ContentType.ApplicationJson;
                string message = propagateApplicationErrorInFault ? e.Message : Messages.GenericFailure;
                content = JsonHelper.Serialize(new { Message = message });

                Trace.Write(new TraceItem()
                {
                    Error = e.Message, Millis = timeKeeper.Stop().TotalMilliseconds
                }, context);
            }

            #endregion

            finally
            {
                logger.Debug($"ContentType: {contentType}");
                logger.Debug($"Content: {content}");
                logger.Info($"statusCode: {statusCode}");

                context.Response.ContentType = contentType;
                context.Response.StatusCode  = statusCode;

                await context.Response.WriteAsync(content);

                double ms = timeKeeper.Stop().TotalMilliseconds;

                Trace.Write(new TraceItem()
                {
                    Millis = ms
                }, context);

                logger.Info($"Request completed in {ms} ms");
            }
        }
Exemplo n.º 5
0
 public override ApiHandlerOutput Process(ApiInputHandler input)
 {
     return(GetOutput(new { Message = Messages.Success }));
 }
Exemplo n.º 6
0
 public override ApiHandlerOutput Process(ApiInputHandler input)
 {
     return(GetOutput(new { Message = $"Response from private API: {Context.Current.User.Username}" }));
 }
Exemplo n.º 7
0
        public override ApiHandlerOutput Process(ApiInputHandler input)
        {
            LoginRequest request = GetEntity <LoginRequest>(input);

            LoginOutput loginOutput = Business.User.Login(request.Username, request.Password);

            if (loginOutput.Result == LoginResult.Failed)
            {
                throw new ApiAccessDeniedException(Messages.LoginFailed);
            }
            else if (loginOutput.Result == LoginResult.PasswordExpired)
            {
                throw new ApiAccessDeniedException(Messages.PasswordExpired);
            }

            if (!string.IsNullOrEmpty(request.Domain))
            {
                List <Entities.Domain> domains = Business.User.GetDomains(loginOutput.User.Username);

                Entities.Domain domain = domains.Where(x => x.Id.ToString().ToLower() == request.Domain.ToLower() || x.Name.ToLower() == request.Domain.ToLower()).FirstOrDefault();

                if (domain == null)
                {
                    domain = NestSearch(domains, request.Domain);

                    if (domain == null)
                    {
                        throw new ApiNotFoundException(request.Domain);
                    }
                }

                Business.User.SetDomain(loginOutput.User.Id, domain.Id);

                loginOutput.User.DomainId = domain.Id;
                loginOutput.User.Domain   = domain;
            }

            if (loginOutput.User.DomainId != Guid.Empty && Business.Domain.HasTwoFactorAuthentication(loginOutput.User.DomainId))
            {
                IAuthProcessor processor = new Skebby();

                processor.GenerateOtp(loginOutput.User.Id, loginOutput.User.DomainId);

                LoginTwoFactorResponse twoFactorResponse = new LoginTwoFactorResponse()
                {
                    Domain = loginOutput.User.DomainId
                };

                return(GetOutput(twoFactorResponse));
            }

            LoginResponse response = new LoginResponse()
            {
                Output = loginOutput
            };

            if (request.Bearer == "true" && loginOutput.User != null)
            {
                string secret = HashHelper.GetSha256(request.Password);

                var p = loginOutput.User.Properties;

                loginOutput.User.Properties.Clear();

                string token = JwtBuilder.Create()
                               .WithAlgorithm(new HMACSHA256Algorithm())
                               .WithSecret(secret)
                               .AddClaim("exp", DateTimeOffset.UtcNow.AddHours(12).ToUnixTimeSeconds())
                               .AddClaim("user", response.Output.User)
                               .Encode();

                logger.Debug($"token generated: {token}");

                Business.User.SaveBearer(loginOutput.User.Id, token);

                response.Bearer = token;

                loginOutput.User.Properties = p;
            }

            input.Context.Session.Set(response.Output.User);

            return(GetOutput(response));
        }
Exemplo n.º 8
0
        public override ApiHandlerOutput Process(ApiInputHandler input)
        {
            OneTimePasswordRequest request = GetEntity <OneTimePasswordRequest>(input);

            if (!Business.OneTimePassword.Exists(request.Username, Guid.Parse(request.Domain), request.Otp))
            {
                throw new ApiAccessDeniedException(Messages.LoginFailed);
            }

            LoginOutput loginOutput = new LoginOutput();

            loginOutput.User = Business.User.Get(request.Username);

            if (loginOutput.User == null)
            {
                ThrowInvalidArgument();
            }

            List <Entities.Domain> domains = Business.User.GetDomains(loginOutput.User.Username);

            Entities.Domain domain = domains.Where(x => x.Id.ToString().ToLower() == request.Domain.ToLower() || x.Name.ToLower() == request.Domain.ToLower()).FirstOrDefault();

            if (domain == null)
            {
                domain = NestSearch(domains, request.Domain);

                if (domain == null)
                {
                    throw new ApiNotFoundException(request.Domain);
                }
            }

            Business.User.SetDomain(loginOutput.User.Id, domain.Id);

            loginOutput.User.DomainId = domain.Id;
            loginOutput.User.Domain   = domain;

            LoginResponse response = new LoginResponse()
            {
                Output = loginOutput
            };

            if (request.Bearer == "true" && loginOutput.User != null)
            {
                string secret = HashHelper.GetSha256(request.Password);

                var p = loginOutput.User.Properties;

                loginOutput.User.Properties.Clear();

                string token = JwtBuilder.Create()
                               .WithAlgorithm(new HMACSHA256Algorithm())
                               .WithSecret(secret)
                               .AddClaim("exp", DateTimeOffset.UtcNow.AddHours(12).ToUnixTimeSeconds())
                               .AddClaim("user", response.Output.User)
                               .Encode();

                logger.Debug($"token generated: {token}");

                Business.User.SaveBearer(loginOutput.User.Id, token);

                response.Bearer = token;

                loginOutput.User.Properties = p;
            }

            input.Context.Session.Set(response.Output.User);

            return(GetOutput(response));
        }
Exemplo n.º 9
0
 public abstract ApiHandlerOutput Process(ApiInputHandler input);