Cuando vamos a abordar un proyecto que es multiidioma debemos de tener en cuenta diversas particularidades a la hora de implementar nuestros desarrollos. Más o menos todos tenemos en cuenta los ficheros de recursos para hacer que la interfaz (que va a visualizar el usuario) se adapte a su idioma, sin embargo solemos olvidarnos de otros aspectos igual de importantes como, por ejemplo, asignar los permisos y que estos no dependan del idioma en el que este nuestro site.
Estos fallos no sólo son comunes en nuestros desarrollos, sino que en productos desarrollados por grandes empresas también tienen estos inconvenientes. ¿Quién no ha estado realizando un desarrollo pensando que el cliente tiene la granja de SharePoint instalada en español y resulta que al final el desarrollo se ejecuta en un entorno en inglés con un Service pack en catalán? Lo cierto, es que Sharepoint se comporta de una forma un tanto peculiar, tal y como vamos a observar a lo largo de este post.
Caso de estudio:
Tenemos un sitio de colaboración MUI (Multilingual User Interface), el idioma por defecto es el inglés, pero la interfaz puede estar tanto en inglés, en catalán o en castellano. Por este motivo, le instalaremos los Service Pack de español y de catalán. Esta es una de las características que trae Office365 para estos sitios.
Una vez instalado el language pack en nuestro sitio, tenemos que activar los lenguajes que va a soportar nuestra aplicación. Para ello, debemos ir a Site Settings–>Site Administration–>Language Settings y activar los idiomas que consideremos oportunos.
En el momento que activamos los idiomas, podremos observar la interfaz en un idioma u otro (dependiendo del idioma que este definido en nuestro navegador).
Problema
Esta característica está muy bien y da muchas facilidades a la hora de establecer sitios multiidioma en SharePoint. Sin embargo, el problema surge cuando queremos realizar diversas acciones en las que existe una dependencia del idioma. El caso de los permisos es un aspecto que tenemos que tener en cuenta, tal y como vamos a ver a continuación.
Dependiendo del idioma en el que nos encontremos, los roles de permisos tienen un nombre u otro. Basta con irnos a la interfaz gráfica y podemos ver que los permisos que podemos asignar correctamente son Read, Leer o Llegir (dependiendo del idioma en el que nos encontremos). También podemos realizarlo mediante el siguiente código:
private string ObtenerGruposdePermisos() { StringBuilder result= new StringBuilder(); var roleDefinition = SPContext.Current.Web.RoleDefinitions; foreach (SPRoleDefinition spRoleDefinition in roleDefinition) { result.AppendLine(spRoleDefinition.Name); } return result.ToString(); }
Si este código lo añadimos en un WebPart (dependiendo del idioma en el que nos encontremos) se visualizará la siguiente información:
Una vez establecido cuál es el entorno en el que nos encontramos y sobre el que vamos a realizar nuestro desarrollo, tenemos el siguiente problema: dependiendo del estado en el que se encuentre un documento, tenemos que cambiar los roles a determinados grupos de seguridad. Para realizar este cambio de seguridad, lo implementaremos dependiendo de un EventReceiver. Para ello, implementamos la siguiente función:
using (SPSite site = new SPSite("http://sf2")) { using (SPWeb web = site.OpenWeb()) { web.AllowUnsafeUpdates = true; var listAdd = web.Lists.TryGetList("Usuarios"); var oGroup = web.Site.RootWeb.Groups.GetByName("Demo"); var roleAssignment = new SPRoleAssignment(oGroup); var roleDefinition = web.RoleDefinitions["Read"]; roleAssignment.RoleDefinitionBindings.Add(roleDefinition); if (!listAdd.HasUniqueRoleAssignments) { listAdd.BreakRoleInheritance(false); } listAdd.RoleAssignments.Add(roleAssignment); listAdd.Update(true); web.AllowUnsafeUpdates = false; } }
El código, en la lista que indicamos, asigna al grupo «Demo» permisos de lectura. En caso de que ésta lista herede permisos del sitio, debemos romper esta herencia mediante la función BreakRoleInheritance con el parámetro a true.
Ahora bien, ¿pensáis que este código funcionará en todos los supuestos?
La respuesta es clara: NO. Ese código lo hemos añadido en un EventRecevier cada vez que se modifica un elemento de una lista. Si modificamos el elemento en una interfaz en inglés, los permisos se modifican sin ningún problema. Sin embargo, si los modificamos en un entorno castellano o catalán, nos encontramos con que los permisos no se han asignado. Consultamos el log y encontramos un error indicando que el Grupo «Read» no lo encuentra. En teoría, el EventReceiver no debería tener dependencia de la interfaz, ya que un receptor se debería ejecutar en el idioma en el que esta instalado SharePoint.
Solución
Para no tener esa dependencia del idioma, se pueden consultar los Roles en base a un enumerado SPRoleType. Para ello, modificamos la forma en la que se obtiene el rol de la siguiente forma:
var roleDefinition = web.RoleDefinitions.GetByType(SPRoleType.Reader);
En caso de que con los Roles por defecto que trae SharePoint no tengamos suficiente, tenemos dos opciones: seguir accediendo por nombre (siempre que pongamos un nombre común para los tres idiomas) o extender el SPRoleType con los roles que hemos añadido.
Conclusión
Muchas veces, cuando hacemos nuestros desarrollos, no nos paramos a pensar las consecuencias que tiene asignar constantes del sistema y las consecuencias que puede ocasionar a nuestro desarrollo. En este caso, asignar permisos (en base al idioma en el que suponemos que se va ejecutar) es un lastre que no podemos ni debemos cometer.
Referencias
http://msdn.microsoft.com/en-us/library/ff800886.aspx
http://blogs.msdn.com/b/varun_malhotra/archive/2008/08/20/how-to-use-role-definitions-across-multiple-language-moss-versions-clean-approach.aspx