Para hacer esto, debe hacer lo siguiente. Si no sabe qué son las "opciones" y los "argumentos", lea optparse background.
Cada "Comando" o "Solicitud" es en realidad una instancia de un modelo. Defina su modelo de Solicitud con todos los parámetros que alguien pueda proporcionar.
Para obtener opciones simples, debe proporcionar un campo con una lista específica de CHOICES. Para opciones que están "on" o "off" (-x
en la línea de comandos) que debe proporcionar una lista de opciones con dos valores humanos comprensibles ("Do X" y "no hacer X".)
Para las opciones con un valor, debe proporcionar un campo que tome el valor de la opción. Debe escribir un Formulario con la validación de este campo. Volveremos a la validación del valor de la opción en un momento.
Para los argumentos, tiene un segundo modelo (con un FK al primero). Esto puede ser tan simple como un solo campo de FilePath, o puede ser más complejo. De nuevo, es posible que también deba proporcionar un Formulario para validar las instancias de este Modelo.
La validación de la opción varía según el tipo de opción. Debe limitar los valores aceptables para que sean el conjunto de caracteres más reducido posible y escribir un analizador que esté absolutamente seguro de pasar solo caracteres válidos.
Sus opciones estarán en las mismas categorías que los tipos de opción en optparse - string, int, long, choice, float y complex. Tenga en cuenta que int, long, float y complex tienen reglas de validación ya definidas por los modelos y formularios de Django. La opción es un tipo especial de cadena, ya soportada por los Modelos y Formas de Django.
Lo que queda son "cadenas". Definir las cadenas permitidas Escribe una expresión regular para esas cuerdas. Validar usando la expresión regular. La mayoría de las veces, nunca puede aceptar presupuestos ("
, '
o `) en ninguna forma.
Paso final. Su modelo tiene un método que emite el comando como una secuencia de cadenas lista para subprocess.Popen
.
Editar
Esta es la columna vertebral de nuestra aplicación. Es tan común que tenemos un único modelo con numerosas formas, cada una para un comando de lote especial que se ejecuta. El modelo es bastante genérico. Los formularios son formas bastante específicas para construir el objeto modelo. Esa es la forma en que Django está diseñado para funcionar, y ayuda a encajar con los patrones de diseño bien pensados de Django.
Cualquier campo que esté "disponible como campos de texto abierto" es un error. Cada campo que está "abierto" debe tener una expresión regular para especificar lo que está permitido. Si no puede formalizar una expresión regular, debe reconsiderar lo que está haciendo.
Un campo que no se puede restringir con una expresión regular no puede ser un parámetro de línea de comandos. Período. Debe almacenarse en una columna de archivo a base de datos antes de ser utilizado.
Editar
gusta esta.
class MySubprocessCommandClass(models.Model):
myOption_1 = models.CharField(choice = OPTION_1_CHOICES, max_length=2)
myOption_2 = models.CharField(max_length=20)
etc.
def theCommand(self):
return [ "theCommand", "-p", self.myOption_1, "-r", self.myOption_2, etc. ]
Su forma es un modelo modelo para este modelo.
No es necesario que save()
las instancias del modelo. Los guardamos para que podamos crear un registro de lo que se ejecutó con precisión.
Leyendo a través de http://blog.littleimpact.de/index.php/2008/08/11/avoiding-shell-injection-in-ruby-python-and-php/ parece que voy a estar bien, así que siempre como shell = False, que es el predeterminado. (Es decir, se ejecutará uno y solo un comando). ¿Esto también es lo que dices? – gotgenes
Sí, eso es lo que estoy diciendo. –