miércoles, 29 de diciembre de 2010

Administración de usuarios/grupos en alfresco (I)

Debido a que la administración de usuarios y grupos en alfresco no ofrece demasiadas posibilidades, estuve indagando un poco en la forma de realizar tareas que eran muy repetitivas con ayuda de javascript. He de agredecer a Pedro Jimenez Caracuel que fue quien me ayudó en un comienzo con esto (estaba bastante perdido....).

De modo que voy a mostrar una serie de scripts que en mi caso son bastante útiles (algunos más que otros).

- anade_user_group.js (añade un usuario a un grupo, puede parecer una tontería, pero nos servirá para extenderlo a varios usuarios y ver de una manera más clara su funcionamiento):
//Variables a completar
var nombregrupo="Nombre del Grupo";
var user="Nombre del usuario";


var groupPrefix="GROUP_";
//Fichero de log
var logFile = space.childByNamePath("documento_salida.txt");
if (logFile == null)
{
logFile = space.createFile("documento_salida.txt");
}
logFile.content ="";
var log = "";
//Obtenemos el ScriptNode para el grupo
var srcGrpNode=people.getGroup(groupPrefix+nombregrupo);
//Obtenemos el ScriptNode para el usuario
var authority = people.getPerson(user);

if(authority && srcGrpNode) //Si el usuario y el grupo existen
{
var listado = people.getMembers(srcGrpNode);
var array_usuarios = [];
for (var i=0;i
{
array_usuarios[i]=(listado[i]).properties["{http://www.alfresco.org/model/content/1.0}userName"];
}
if (array_usuarios.indexOf(user)== -1) //Si el usuario no existe en el grupo, lo insertamos
{
people.addAuthority(srcGrpNode,authority);
log+="1.-añadido usuario:" + user + " al grupo " + nombregrupo;
}
else
{
log+="1.- El usuario: " + user + " ya esta asignado al grupo " + nombregrupo;
}

}
else //Ha salido porque el grupo o el usuario no existen
{
if (authority)
log+="1.- El grupo: " + nombregrupo + " no existe" ;
else
log+="1.- El usuario: " + user + " no existe" ;
}
logFile.content += log;



- anade_users_group.js (añade una lista de usuarios a un grupo):

//Variables a completar
var users = new Array ('usuario1','usuario2','usuario3');
var grupo="Nombre del grupo";

var groupPrefix="GROUP_";
//Fichero de log
var logFile = space.childByNamePath("documento_salida.txt");
if (logFile == null)
{
logFile = space.createFile("documento_salida.txt");
}
logFile.content ="";
var log = "";

var srcGrpNode=people.getGroup(groupPrefix+grupo);
if (srcGrpNode)
{
//Se obtiene un array con los miembros del grupo.
var listado = people.getMembers(srcGrpNode);
var array_usuarios = [];
for (var i=0;i
{
array_usuarios[i]=(listado[i]).properties["{http://www.alfresco.org/model/content/1.0}userName"];
}
log+="Grupo: " + grupo + "\n";
//Recorremos el array de usuario para insertarlos en el grupo
for(var i=0;i
{
var authority = people.getPerson(users[i]);
if(authority) //Si el usuario existe
{
if (array_usuarios.indexOf(users[i])== -1) //Y no existe aun en el grupo
{
people.addAuthority(srcGrpNode,authority);
log+="- añadido usuario:" + users[i] + " al grupo " + grupo + " \n";
}
else
{
log+="- El usuario: " + users[i] + " ya existe en el grupo " + grupo + "\n";
}
}
else
{
log+="- No existe usuario:" + users[i] + "\n";
}
}
}
else
{
log+="El grupo: " + grupo + " no existe.\n";
}
logFile.content += log;


- anade_user_group_list.js (añade un usuario a un listado de grupos):

//Variables a completar
var grupos = new Array ('grupo1','grupo2','grupo3');
var user="Nombre del usuario";
var groupPrefix="GROUP_";
var logFile = space.childByNamePath("documento_salida.txt");
if (logFile == null)
{
logFile = space.createFile("documento_salida.txt");
}
logFile.content ="";
var log = "";
var authority = people.getPerson(user);
if(authority)
{
for(var i=0;i
{
var srcGrpNode=people.getGroup(groupPrefix+grupos[i]);
if (srcGrpNode)
{
var listado = people.getMembers(srcGrpNode);
var array_usuarios = [];
for (var j=0;j
{
array_usuarios[j]=(listado[j]).properties["{http://www.alfresco.org/model/content/1.0}userName"];
}
if (array_usuarios.indexOf(user)== -1) //Si el usuario no existe en el grupo, lo insertamos
{
people.addAuthority(srcGrpNode,authority);
log+="- añadido usuario:" + user + " al grupo " + grupos[i] + " \n";
}
else
{
log+="- El usuario: " + user + " ya esta en el grupo " + grupos[i] + "\n";
}
}
else
{
log+="- El grupo: " + grupos[i] + " no existe.\n";
}
}//final for
}
else
{
log+="- No existe usuario:" + user + "\n";
}
logFile.content += log;

sábado, 4 de diciembre de 2010

Variables jvm

A raíz de una auditoría realizada sobre varios entornos de Alfresco, nos aconsejaron una serie de valores a indicar en la máquina virtual de java. Aprovecho para aclarar algunas de estas variables.

Una posible configuración:

JAVA_OPTS='-Xms1024m -Xmx1536m -Xmn256m -Xss128k -server -d64
-Xloggc:/opt/alfresco/tomcat/logs/gc.log -Xcheck:jni -Xconcurrentio -XX:
+UseParNewGC -XX:+CMSPermGenSweepingEnabled
-Dsun.rmi.dgc.server.gcInterval=600000
-Dsun.rmi.dgc.client.gcInterval=600000 -XX:SurvivorRatio=8
-XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31 -XX:+UseParNewGC
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled'


Significado:

-server, solo puede haber una opción en la variable, de esta manera activamos Server Hotspot VM.

-d32/-d64, activa el modelo de datos de 32/64bits, por lo que en un entorno de pruebas puede confirmarse la mejor configuración para nuestros entornos con una JVM, recomendable siempre la última revisión (para solución de incidencias detectadas por el fabricante Sun), específica para nuestra plataforma y activando o desactivando el modelo que interese para aumentar estabilidad o rendimiento.

-Xloggc://logs/gc.log, podemos almacenar un log para las acciones del recolector de basura.

-Xcheck:jni, nos muestra comprobaciones adicionales de funciones jni.

-Xconcurrentio, activa opciones internas adicionales para la sincronización basada en hilos LWP que aumentan el rendimiento.

-Xmx1536m -Xms1024m -Xmn256m, mediante la optimización de estos tres valores especificamos la memoria total de objetos heap inicial y máxima y la memoria young generation, donde se almacenan todos los objetos de la aplicación web desde su primera carga en memoria.

-Xss128k, podemos especificar memoria de pila para cada hilo, si hay problemas relacionados se recomienda aumentar a 256k.

-XX:SurvivorRatio=8, el índice de supervivencia es la proporción entre el espacio de objetos nuevos (eden) y el espacio de supervivientes de la sección de objetos jóvenes del almacenamiento dinámico. Al aumentar este valor se optimiza la JVM para las aplicaciones en las que se crean muchos objetos y se conservan pocos objetos.

-XX:TargetSurvivorRatio=90, permite ocupar el 90% del espacio de supervivientes en lugar del 50%, permitiendo mejor utilización del espacio de memoria superviviente.

-XX:MaxTenuringThreshold=31 -XX:MaxPermSize=192m, con estos valores aumentaremos el rendimiento global de nuestra instalación.

-XX:+UseParNewGC, activa recolección de basura en paralelo en la memoria young generation.

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled, con estos valores activamos la recolección de basura concurrente CMS para la memoria permanente, siendo altamente recomendable.


* Propiedades de sistema, con el indicador -D=”valor” indicamos muchas características:


-Dsun.rmi.dgc.server.gcInterval=600000
-Dsun.rmi.dgc.client.gcInterval=600000, con estos valores podemos establecer el intervalo de tiempo en milisegundos para la ejecución del recolector de basura (10 minutos) en la máquina hotspot que hemos elegido.

Aclaración sobre algunas variables:

-Xms1536m : Tamaño inicial de Java heap, por defecto: 4MB
-Xmx1536m : Tamaño máximo de Java heap, por defecto: de 16 a 512 MB

Se suele recomendar que estas dos variables tengan el mismo valor, con objeto de no hacer trabajar a la jvm para agrandar este espacio (ya que le estamos indicando el tamaño que deberá tener desde un principio).

-XX:PermSize=512m : Tamaño inicial de la región permanente
-XX:MaxPermSize=512m : Tamaño máx de la región permanente, por defecto
64MB

Decompilador Java

Por si tenéis que decompilar algún class de java....

http://jdec.sourceforge.net/

Lo descomprimís en alguna carpeta y le dais permiso de ejecución a su contenido, luego ejecutáis ./Jdec-UI.sh

Hay unos parámetros que se tienen que cambiar, una vez abierta la aplicación, presionad Alt+Mays+A, y en el listado podéis poner algo así:

Output_Mode
file
Log_Mode
file
Output_Folder_Path
/home/rafa/Escritorio
Output_File_Extension
java
LOG_LEVEL
2
Log_File_Path
/opt/jdec/log.txt
UI_LOG_FILE_PATH
/opt/jdec/log2.txt
JAVA_CLASS_FILE
/opt/jdec/
JAR_FILE_PATH
/opt/jdec/
Show_Imports
true
JDec_Option
dc
Temp_Dir
/home/rafa/Escritorio
Inner_Depth
2
Inline_Anonymous_Inner_Class_Content
false
Interpret_Exception_Table
false
Interpret_Non_ASCII
true
Force_Non_ASCII
true
Skip_Class_Version_Check
true
int_local_var_prefix
aInt
byte_local_var_prefix
aByte
short_local_var_prefix
aShort
char_local_var_prefix
aChar
float_local_var_prefix
aFloat
double_local_var_prefix
aDouble
long_local_var_prefix
aLong
boolean_local_var_prefix
aBoolean
string_local_var_prefix
aString
other_local_var_prefix
other

Volcado de memoria (hprof)

Debido a los errores de memoria cada vez más frecuentes (tipo java.lang.OutOfMemoryError: PermGen space failure) en las aplicaciones java que administramos en entornos de producción y a que en la mayoría de los casos se debe a un error de programación, java nos da la posibilidad de añadir una variable para realizar un volcado de la memoria.

Con esto obtenemos en un fichero una copia exacta del contenido de la memoria de la jvm en el momento del error. Este fichero nos servirá para tener una base sobre la cual estudiar el origen del problema (hay herramientas para procesar este tipo de ficheros, como jvisualvm).

Dicha variable sería:

-XX:HeapDumpPath=/ruta/donde/guardar/el/fichero/ -XX: +HeapDumpOnOutOfMemoryError


Sólo es factible sobre la versión de java 1.6 (por lo que no se podría aplicar a todas las aplicaciones).

Este fichero puede ser analizado con distintas herramientas: JVisualVM, Eclipse Memory Analyzer...

Si además quieres que ser avisado por correo cuando esto se produzca, se puede establecer en el cron (cada 5 min por ejemplo) que lance un script parecido al siguiente (este está hecho en python):

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import os, string, datetime, time, smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

#Variables
servidor_de_correo = "servidor de correo"
emisor= "maquina@dominio"

#Funcion para el envio de correo
def sendMail(to, subject, text, server=servidor_de_correo):
assert type(to)==list
fro = emisor

COMMASPACE = ', '
msg = MIMEMultipart()
msg['From'] = fro
msg['To'] = COMMASPACE.join(to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject

msg.attach( MIMEText(text) )


smtp = smtplib.SMTP(server)
smtp.sendmail(fro, to, msg.as_string() )
smtp.close()


#Funcion de registro de log
def log (texto):
now = datetime.datetime.now()
f = open(fichero_log, 'a')
f.write(str (now.ctime()) + ' -> ' + texto + '\n')
f.close()

#Variables
cuenta_de_correo = "cuenta de correo donde mandar el aviso"
fichero_pid = "/var/run/tomcat5.pid"
f = open(fichero_pid,"r")
pid = str(f.read()).strip()
fichero_hprof = "java_pid" + pid + ".hprof"
fichero_log = "/ruta_fichero_log/comprueba.log"
existe = os.path.isfile("/tmp/" + fichero_hprof)
if existe:
log("Se ha creado el volcado de memoria.")
sendMail(
["cuenta_de_correo"],
"Volcado de memoria","Se ha producido un error de memoria provocando el volcado en el fichero " + fichero_hprof
)

else:
log("No se ha producido error de memoria ni volcado.")



El script simplemente estará revisando la existencia del fichero de volcado, que suele denominarse:

java_pid15546.hprof

donde 15546 es el pid del tomcat donde hemos configurado la variable para el hprof.

En cuanto detecte que existe, mandará un correo a la cuenta especificada.

alf_bootstrap_lock

Se trata de un error muy típico de Alfresco (al menos en versiones 2.1) cuando se produce alguna complicación de actualización o un reinicio inesperado. Es una medida de seguridad que deja bloqueado el sistema mostrando el siguiente mensaje de error:

Caused by: org.alfresco.error.AlfrescoRuntimeException: A previous schema upgrade failed. Revert to the original database before attempting
the upgrade again.

Si se ha producido por algún reinicio inesperado, la solución es simplemente elminar la tabla:

alf_bootstrap_lock

Tras esto, arrancaremos alfresco sin ningún problema.

jueves, 25 de noviembre de 2010

Balanceo con mod_proxy_balancer

Una opción de balanceo de carga que nos ofrece apache a partir de la versión 2.1 es mod_proxy_balancer. Hoy he realizado una pequeña configuración para balancear una aplicación que correo sobre dos tomcat. Básicamente la configuración consiste en lo siguiente (esto lo configuro dentro de un virtual):


<VirtualHost *:80>

ServerName prueba.dominio.es

ErrorLog logs/error.log

CustomLog logs/access.log common

RewriteEngine On



ProxyPreserveHost on

<Proxy balancer://cluster>

BalancerMember http://tomcat1:8080 loadfactor=1 route=clustnode1

BalancerMember http://tomcat2:8080 loadfactor=1 route=clustnode2

Order Deny,Allow

Allow from all

</Proxy>



<Location /aplicacion>

ProxyPass balancer://cluster/aplicacion stickysession=JSESSIONID

ProxyPassReverse balancer://cluster/aplicacion

Order Deny,Allow

Allow from all

</Location>



<Location /balancer-manager>

SetHandler balancer-manager

Order Deny,Allow

Allow from all

</Location>


</VirtualHost>

Por partes:


ProxyPreserveHost on

<Proxy balancer://cluster>

BalancerMember http://tomcat1:8080 loadfactor=1 route=clustnode1

BalancerMember http://tomcat2:8080 loadfactor=1 route=clustnode2

Order Deny,Allow

Allow from all

</Proxy>


Se define el balanceo (miembros, factor de carga, ruta, ...). Importante poner "ProxyPreserveHost on", porque si no se pone, al quitar una máquina del balanceo, si estabas en ella, cuando intentes acceder otra vez te redirige a la otra máquina, pero con la ip en vez de la url. También debes definir en route el valor que tengas puesto en cada uno de los jvmRoute (en server.xml) de los tomcat:


<Engine name="Catalina" defaultHost="localhost" jvmRoute="clustnode1">



<Location /aplicacion>

ProxyPass balancer://cluster/aplicacion stickysession=JSESSIONID

ProxyPassReverse balancer://cluster/aplicacion

Order Deny,Allow

Allow from all

</Location>


Aquí ya hacemos el proxy, simplemente le decimos que las peticiones para /aplicacion lo mande al cluster. Importante definir stickysession para que te mande siempre al mismo nodo.

El /balancer-manager no es mas que para administrar vía web el balanceo....

miércoles, 24 de noviembre de 2010

Exámenes LPIC

Buenas, para aquellos que estén interesados, para marzo del año que viene se realizan los exámenes del LPIC en la ETSII de Sevilla. Aquí tenéis el enlace:

http://www.concursosoftwarelibre.org/1011/certificado-lpi

Nos vemos allí ;)

Manipular pdf's desde la línea de comandos

Si necesitas extraer páginas de un pdf, unir varios pdf en uno, obtener metadatos ... una forma muy fácil y efectiva de hacerlo en con pdftk.

En el siguiente post viene muy bien expliado:

http://danubuntu.wordpress.com/2008/04/05/manipular-archivos-pdf-con-pdftk/

Ejemplo: queremos extraer las páginas 25 a 36 de un archivo PDF

$ pdftk A=documento1.pdf cat A25-36 output documento_nuevo_pag_25_a_36.pdf

Ejemplo: obtener informe con los metadatos de un pdf
$ pdftk documento.pdf dump_data output informe.txt


lunes, 22 de noviembre de 2010

Contar número de documentos en un espacio de Alfresco

Siguiendo la mísma línea que en el script para dar permisos a un espacio copiado en alfresco, podemos recorrer un espacio de forma recursiva para obtener otros datos que nos pueden ser muy útiles. En este caso, obtenemos el número de documentos que contiene el espacio y el peso de este:

//Crea log en el espacio personal de quien se loga.
var logFile = userhome.childByNamePath("recorre.log");
if (logFile == null)
{
logFile = userhome.createFile("recorre.log");
}
logFile.content ="";
var log = "";



//Funcion que cuenta los docuementos y obtiene el peso de un espacio de forma recursiva.
function cuenta(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
cuenta(n);
}
else
{
total += 1;
peso += n.size;
}
}
}

//Comienza main.
var total = 0;
var peso = 0;
cuenta(space);
log += "El total de documentos del espacio " + space.name + "es: " + total + "\n";
log += "El tamaño del espacio es: " + space.name + "es: " + peso/1024/1024 + " MB\n";
logFile.content += log;
//FIN

Este script lo debemos ejecutar como una acción sobre el espacio que queramos consultar.

Hacemos la división para obtener el valor en MB.

domingo, 21 de noviembre de 2010

Screen para no perder sesiones...

Ya me ha pasado más de una vez que mientras ejecuto algún trabajo a través de ssh, por algún motivo he perdido la conexión y también lo que estaba haciendo en el servidor sobre el que trabajaba.

Para evitar estas situaciones podemos hacer uso de screen. screen es un manejador de sesiones que nos permite tener en segundo plano la ejecución de un programa. No sólo sirve para trabajar sobre ssh, también lo podemos usar en local.

Su uso es muy sencillo. Una vez conectados, simplemente tenemos que ejecutar:

rafa@rafa-laptop:~$ screen

A partir de ahora todo lo que ejecutemos estará asociado a este "screen".

Si la conexión se cierra, podemos recuperar lo que teníamos en ese screen con:

rafa@rafa-laptop:~$ screen -rx

Y aparecerá la ejecución que teníamos.

screen admite muchas más opciones, como por ejemplo:

  • Si queremos dejar un screen abierto ejecutando algún comando, pulsaremos: ^a d (CTRL+A D).
  • Para abrir una nueva ventana: ^a c (CTRL+A C).
para más info, ya sabéis: man screen

sábado, 20 de noviembre de 2010

Añadir nuevas versiones de java a alternatives

Muchas veces necesitamos trabajar con distintas versiones de java. Podemos tener instaladas todas las versiones que queramos y utilizar en cada momento la que nos convenga.

Para instalar una nueva versión haríamos lo siguiente:
  • Descargas el .bin de la versión de java que queramos, le das permisos de ejecución y lo ejecutas.
  • Una vez aceptadas las condiciones, se habrá creado una carpeta con el nombre de la versión. Mueves la carpeta a /usr/lib/jvm/.
  • Ahora lo añadimos a alternatives:

update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/version_que_sea/bin/java" 1


Para usar esta versión tan sólo tenemos que indicar lo siguiente:

update-alternatives --set java /usr/lib/jvm/version_que_sea/bin/java

Y listo. También podemos ver las distintas versiones que tenemos:

update-alternatives --list java

En mi caso, la salida sería la siguiente:



jueves, 18 de noviembre de 2010

Mantener los permisos al copiar un espacio en Alfresco 3.2r

Buenas, supongo que más de uno se habrá encontrado con este bug de alfresco: http://issues.alfresco.com/jira/browse/ALF-2638

La cosa es que al copiar un espacio, se copia correctamente su contenido, pero no mantiene los permisos que tenga aplicados (lo cual es un verdadero problema cuando se trata de espacios con una estructura compleja y muchos grupos).

Como de momento parece que no hay solución para este bug (si existe, por favor que me lo indiquen ;) ), he confeccionado un js para que una vez se ha hecho la copia de un espacio, se apliquen los permisos. El proceso sería: copiar y pegar el espacio, renombrarlo por "NombreDeEspacioOriginal"_COPIA (es decir, el nombre original con el sufijo _COPIA) y aplicarle una acción para que ejecute el script.

   //Obtiene el path del espacio _COPIA y genera el path del origen.
var ruta_destino = (space.displayPath + "/" + space.name).replace("/Empresa/","");
var ruta_origen = ruta_destino.replace("_COPIA","");
//Crea log en el espacio personal de quien se loga.
var logFile = userhome.childByNamePath("recorre.log");
if (logFile == null)
{
logFile = userhome.createFile("recorre.log");
}
logFile.content ="";
var log = "";
//Funcion que recorre un espacio para copiar sus permisos sobre otro espacio copia.
function recorre(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
//Compongo path origen
cadena_origen = n.displayPath + "/" + n.name;
//Compongno path destino
var replace_1 = "/Empresa/" + ruta_origen + "/";
var replace_2 = ruta_destino + "/";
cadena_destino = cadena_origen.replace(replace_1, replace_2);
//Compongo ScriptNode destino
var espacio_fin = companyhome.childByNamePath(cadena_destino);
log += n.name + " es un subespacio de " + n.parent.name + ".\n";
if (n.inheritsPermissions())
{
log += n.name + " hereda permisos." + "\n";
espacio_fin.setInheritsPermissions(true);
}
var cadena = n.getPermissions();
for each (k in cadena)
{
var permisos = k.split(';');
log += "Grupo: " + permisos[1] + "\n";
log += "Permiso: " + permisos[2] + "\n";
espacio_fin.setPermission(permisos[2],permisos[1]);
}
recorre (n);
}
}
}
//Funcion que quita los permisos otorgados nada mas copiar.
function quita_permisos(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
if (n.inheritsPermissions())
{
n.setInheritsPermissions(false);
}
var cadena = n.getPermissions();
for each (k in cadena)
{
var permisos = k.split(';');
log += "Grupo: " + permisos[1] + "\n";
log += "Permiso: " + permisos[2] + "\n";
n.removePermission(permisos[2],permisos[1]);
}
quita_permisos (n);
}
}
}
//Comienza main. El espacio sobre el que se invoque debe tener el sufijo "_COPIA"
var pos = ruta_destino.lastIndexOf("_COPIA");
if (pos > 0)
{
//Se obtien los ScriptNode a partir de la ruta de los espacios.
var espacio_origen = companyhome.childByNamePath(ruta_origen);
var espacio_destino = companyhome.childByNamePath(ruta_destino);
//Primero quitamos los permisos del copiado.
quita_permisos(espacio_destino);
//Recorremos el espacio origen para dar los permisos al destino.
recorre(espacio_origen);
//Se aplican los permisos al espacio padre destino.
log += espacio_origen.name + " es el espacio padre. \n";
if (espacio_origen.inheritsPermissions())
{
espacio_destino.setInheritsPermissions(true);
}
var cadena_permisos = espacio_origen.getPermissions();
for each (k in cadena_permisos)
{
var permisos_origen = k.split(';');
log += "Grupo: " + permisos_origen[1] + "\n";
log += "Permiso: " + permisos_origen[2] + "\n";
espacio_destino.setPermission(permisos_origen[2],permisos_origen[1]);
}
}
else
{
log += "El espacio no tiene sufijo _COPIA \n";
}
logFile.content += log;
//FIN

Para quien no conozca la api de alfresco 3.2: http://wiki.alfresco.com/wiki/3.2_JavaScript_API

Lo que hace es recorrer el espacio original recursivamente para obtener los permisos y si tiene o no herencia para aplicarlos sobre el espacio donde se ejecuta el script. Antes se deben quitar los permisos aplicados al copiar y posteriormente hacer lo mismo sobre el espacio padre (ya que no se contempla en la recursión).

Si el espacio no lleva el sufijo _COPIA no hará nada.

También se mantiene un log en el espacio home de quien lo lance.

Espero que os sea útil.

Un saludo.


CORRECCIÓN:
Buenas, mando una corrección a este script. Había un par de cosas que se me pasaron. Una, que sólo activaba la herencia si el original la tenía, pero no la desactivaba en caso de no tenerla (y por defecto la activa). Dos, a la hora de añadir los permisos, si el espacio heredaba, añadía todos los permiso heredados, lo cual no debería hacer (aunque el resultado en la práctica será lo mismo, ya que los estaba heredando). Se observa que si no tiene herencia, los permisos los copia de forma adecuada. Por tanto lo que hago es desactivar temporalmente la herencia en el original para hacer la copia.

Gracias Jose Luis por haberte dado cuenta y por avisarme....

//Obtiene el path del espacio _COPIA y genera el path del origen.

var ruta_destino = (space.displayPath + "/" + space.name).replace("/Empresa/","");

var ruta_origen = ruta_destino.replace("_COPIA","");



//Crea log en el espacio personal de quien se loga.

var logFile = userhome.childByNamePath("recorre.log");

if (logFile == null)

{

logFile = userhome.createFile("recorre.log");

}

logFile.content ="";

var log = "";



//Funcion que recorre un espacio para copiar sus permisos sobre otro espacio copia.

function recorre(doc)

{

for each (n in doc.children)

{

if (n.isContainer)

{

//Compongo path origen

cadena_origen = n.displayPath + "/" + n.name;

//Compongno path destino

var replace_1 = "/Empresa/" + ruta_origen + "/";

var replace_2 = ruta_destino + "/";

cadena_destino = cadena_origen.replace(replace_1, replace_2);

//Compongo ScriptNode destino

var espacio_fin = companyhome.childByNamePath(cadena_destino);



log += n.name + " es un subespacio de " + n.parent.name + ".\n";

if (n.inheritsPermissions())

{

log += n.name + " hereda permisos." + "\n";

var hereda = true;

n.setInheritsPermissions(false);

} else

{

log += n.name + " no hereda permisos." + "\n";

var hereda = false;

}

var cadena = n.getPermissions();

for each (k in cadena)

{

var permisos = k.split(';');

log += "Grupo: " + permisos[1] + "\n";

log += "Permiso: " + permisos[2] + "\n";

espacio_fin.setPermission(permisos[2],permisos[1]);

}

espacio_fin.setInheritsPermissions(hereda);

n.setInheritsPermissions(hereda);

recorre (n);

}

}

}



//Funcion que quita los permisos otorgados nada mas copiar.

function quita_permisos(doc)

{

for each (n in doc.children)

{

if (n.isContainer)

{

if (n.inheritsPermissions())

{

n.setInheritsPermissions(false);

}



var cadena = n.getPermissions();

for each (k in cadena)

{

var permisos = k.split(';');

log += "Grupo: " + permisos[1] + "\n";

log += "Permiso: " + permisos[2] + "\n";

n.removePermission(permisos[2],permisos[1]);

}

quita_permisos (n);

}

}

}



//Comienza main. El espacio sobre el que se invoque debe tener el sufijo "_COPIA"

var pos = ruta_destino.lastIndexOf("_COPIA");

if (pos > 0)

{

//Se obtien los ScriptNode a partir de la ruta de los espacios.

var espacio_origen = companyhome.childByNamePath(ruta_origen);

var espacio_destino = companyhome.childByNamePath(ruta_destino);



//Primero quitamos los permisos del copiado.

quita_permisos(espacio_destino);

//Recorremos el espacio origen para dar los permisos al destino.

recorre(espacio_origen);

//Se aplican los permisos al espacio padre destino.

log += espacio_origen.name + " es el espacio padre. \n";

if (espacio_origen.inheritsPermissions())

{

var hereda = true;

espacio_origen.setInheritsPermissions(false);

} else

{

var hereda = false;

}

var cadena_permisos = espacio_origen.getPermissions();

for each (k in cadena_permisos)

{

var permisos_origen = k.split(';');

log += "Grupo: " + permisos_origen[1] + "\n";

log += "Permiso: " + permisos_origen[2] + "\n";

espacio_destino.setPermission(permisos_origen[2],permisos_origen[1]);

}

espacio_origen.setInheritsPermissions(hereda);

espacio_destino.setInheritsPermissions(hereda);

}

else

{

log += "El espacio no tiene sufijo _COPIA \n";

}



logFile.content += log;

//FIN

Obtener informacion de repositorios a través de los metadatos .git publicados por error

 A raiz de CTF realizado recientemente, me ha parecido interesante publicar este post sobre los errores de seguridad que se encuentran en mu...