Current section
Files
Jump to
Current section
Files
lib/validation.ex
defmodule Argos.Validation do
@moduledoc """
Módulo de validación de inputs para Argos.
Proporciona funciones de validación exhaustivas para prevenir errores
y mejorar la seguridad del sistema.
"""
@max_process_name_length 255
@process_name_pattern ~r/^[a-zA-Z0-9_.-]+$/
@doc """
Valida un nombre de proceso.
## Validaciones
- Debe ser un string no vacío
- Longitud máxima: 255 caracteres
- Solo caracteres alfanuméricos, puntos, guiones y guiones bajos
## Ejemplos
iex> Argos.Validation.validate_process_name("my_process")
:ok
iex> Argos.Validation.validate_process_name("")
{:error, "Process name cannot be empty"}
iex> Argos.Validation.validate_process_name("invalid@name")
{:error, "Process name contains invalid characters"}
"""
@spec validate_process_name(String.t()) :: :ok | {:error, String.t()}
def validate_process_name(name) when is_binary(name) do
cond do
String.length(name) == 0 ->
{:error, "Process name cannot be empty"}
String.length(name) > @max_process_name_length ->
{:error, "Process name too long (max #{@max_process_name_length} characters)"}
not String.match?(name, @process_name_pattern) ->
{:error, "Process name contains invalid characters"}
true ->
:ok
end
end
def validate_process_name(_invalid) do
{:error, "Process name must be a string"}
end
@doc """
Valida un comando a ejecutar.
## Validaciones
- No puede ser nil
- Si es string, no puede estar vacío
- Si es lista, debe tener al menos un elemento
## Ejemplos
iex> Argos.Validation.validate_command("echo test")
:ok
iex> Argos.Validation.validate_command("")
{:error, "Command cannot be empty"}
iex> Argos.Validation.validate_command(["echo", "test"])
:ok
"""
@spec validate_command(String.t() | [String.t()] | term()) :: :ok | {:error, String.t()}
def validate_command(command) when is_binary(command) do
if String.trim(command) == "" do
{:error, "Command cannot be empty"}
else
:ok
end
end
def validate_command(command) when is_list(command) do
if Enum.empty?(command) do
{:error, "Command list cannot be empty"}
else
:ok
end
end
def validate_command(nil) do
{:error, "Command cannot be nil"}
end
def validate_command(_invalid) do
{:error, "Command must be a string or a list of strings"}
end
@doc """
Valida una especificación de worker.
## Validaciones
- `id` no puede ser nil
- `tasks` debe ser una lista no vacía
## Ejemplos
iex> Argos.Validation.validate_worker_spec(%{id: :w1, tasks: [fn -> :ok end]})
:ok
iex> Argos.Validation.validate_worker_spec(%{id: nil, tasks: [fn -> :ok end]})
{:error, "Worker id cannot be nil"}
iex> Argos.Validation.validate_worker_spec(%{id: :w1, tasks: []})
{:error, "Worker tasks cannot be empty"}
"""
@spec validate_worker_spec(map()) :: :ok | {:error, String.t()}
def validate_worker_spec(%{id: id, tasks: tasks}) when is_list(tasks) do
cond do
id == nil ->
{:error, "Worker id cannot be nil"}
Enum.empty?(tasks) ->
{:error, "Worker tasks cannot be empty"}
true ->
:ok
end
end
def validate_worker_spec(_invalid) do
{:error, "Worker spec must be a map with :id and :tasks keys"}
end
@doc """
Escapa un nombre de proceso para prevenir injection en comandos shell.
## Ejemplos
iex> Argos.Validation.escape_process_name("my_process")
"my_process"
iex> Argos.Validation.escape_process_name("process'name")
"process'\\''name"
"""
@spec escape_process_name(String.t()) :: String.t()
def escape_process_name(name) when is_binary(name) do
String.replace(name, "'", "'\\''")
end
@doc """
Valida un path de archivo o directorio.
## Validaciones
- Debe ser un string no vacío
- No puede contener caracteres peligrosos
## Ejemplos
iex> Argos.Validation.validate_path("/path/to/file")
:ok
iex> Argos.Validation.validate_path("")
{:error, "Path cannot be empty"}
"""
@spec validate_path(String.t()) :: :ok | {:error, String.t()}
def validate_path(path) when is_binary(path) do
if String.trim(path) == "" do
{:error, "Path cannot be empty"}
else
:ok
end
end
def validate_path(_invalid) do
{:error, "Path must be a string"}
end
end