miércoles, 20 de agosto de 2008

Post como anónimo en lista de discusión

Los campos Autor y Modificador de elementos en Listas y Librerías no se pueden modificar por ser de solo lectura, incluso por código nos regresa una excepción del tipo “read only”. Lo que yo necesitaba era poder hacer que una lista de discusión tuviera la capacidad de permitir a los usuarios ocultar su identidad al momento de generar una pregunta o dar respuesta dentro de la lista.

La verdad busque un buen rato por internet pero encontré muy poco que me sirviera de ayuda por lo que se me ocurrió otra alternativa no del todo optima pero funcional, llamémosle chapusa.
A la lista de discusión le agregue un campo llamado Anónimo del tipo “Si o No”.

De esta forma tengo manera de controlar si el usuario quiere que su nombre aparezca como Autor del elemento o por el contrario quiere quedar como anónimo.

Ahora viene crear el manejador de evento de la lista, para saber cómo crear un evento para una lista ver este post Los eventos en WSS3 allí explica lo que son los eventos y los diferentes tipos que existen.

Deberemos sobrescribir el método ItemAdded, dentro tomaremos los valores que el usuario esta guardando en ese momento y en caso de que el usuario haya seleccionado el check de “Anónimo”, utilizaremos un impersonalizador para crear un nuevo elemento por código con un usuario diferente al actual, para esto debemos tener ya un usuario creado llamado Anónimo (o como quieras que aparezca en los elementos), y una vez que creamos el nuevo elemento con el usuario impersonalizado solo nos queda borrar el elemento que el usuario actual agrego como nuevo.

Código:
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
if (item["Anonimo"].ToString() == "True")
{
DisableEventFiring();
SPUser userYo = item.Web.AllUsers["dominio\\Anonimo"];
SPUserToken miSigno = userYo.UserToken;
SPSite impersSiteCollection = new SPSite(item.Web.Url, miSigno);
SPWeb impersWeb = impersSiteCollection.OpenWeb();

if (item["IsRootPost"].ToString() == "0")
{
SPListItemCollection miListaItemCol = impersWeb.Lists["Discusion"].Items;
SPListItem parentItem = miListaItemCol.GetItemById((int)item["ID"]);
SPListItem nuevoItem = SPUtility.CreateNewDiscussionReply(parentItem);
nuevoItem["Categoria"] = item["Asunto"];
nuevoItem["Detalle"] = item["Cuerpo"];
nuevoItem["Anonimo"] = item["Anonimo"];
item.Delete();
nuevoItem.Update();
}
else
{
SPListItemCollection miListaItemCol = impersWeb.Lists["Discusion"].Items;
SPListItem nuevoItem = miListaItemCol.Add();
nuevoItem["Categoria"] = item["Asunto"];
nuevoItem["Detalle"] = item["Cuerpo"];
nuevoItem["Anonimo"] = item["Anonimo"];
item.Delete();
nuevoItem.Update();
}
EnableEventFiring();
}
}

Una vez que compila se deberá agregar firmar y agregar la dll al GAC del servidor.

Para asociar el evento con la lista de discusión que nos interesa podemos usar esta herramienta EventHandlerExplorer. (ejemplo de uso aquí).

Y ahora tenemos una lista de discusión con opción a postear comentarios como anónimos dentro de un site de sharepoint.

jueves, 7 de agosto de 2008

Quitar el acceso anónimo a un elemento de una lista o librería con permisos de acceso anónimo

Cuando tengamos una lista o librería de documentos con acceso anónimo habílitado en ella y queramos que uno varios de los elementos de esa lista no puedan ser visible para los usuarios anónimos, basta con editar los permisos de ese elemento y asi dejaran de heredar los permisos de la lista o librería.

Lo vemos mejor con un ejemplo

Tenemos la lista TEST. Configuramos sus permisos para que los elementos de la lista sean visibles a los usuario anónimos.

Entramos en permisos para esta lista

y despues de editar los permisos en Configuración --> Acceso anónimo



Marcamos ver elementos y aceptamos


Volvemos a la lista, y ahora vamos a quitar el acceso anónimo al Elemento 3. Desplegamos el menu del elemento en cuestión, y pinchamos en Administrar Permisos



Ahora basta con Editar los permisos

Este elemento no será visible para los usuarios anónimo.
Saludos
Emilio Albo

lunes, 4 de agosto de 2008

Iniciar automáticamente un workflow asociado a un formulario de Infopath con usuario anónimo

Aprovechando el post anterior y viendo que el administrador del sistema no inicia automaticamente un workflow al crearse un elemento, basta con agregar el siguiente código al codigo del post anterior (en rojo el código ya agregado en el post anterior).


folder.Files.Add(formName + ".xml", data, true);
//**************
// Iniciar workflow
//**************
Microsoft.SharePoint.SPListItem ListI = null;
foreach (Microsoft.SharePoint.SPFile FI in folder.Files)
{
//Inscripcion_Evento de Prueba_mm_mm
if (FI.Name.ToString() == formName + ".xml")
{
ListI = FI.Item;
//b = ListI.ID.ToString();
}
}
Microsoft.SharePoint.Workflow.SPWorkflowAssociation WFA = null;
foreach (Microsoft.SharePoint.Workflow.SPWorkflowAssociation wf in Library.WorkflowAssociations)
{
if (wf.Name.Equals("Nombre de tu workflow"))
{
WFA = wf;
}
}
foreach (SPWorkflow wf2 in ListI.Workflows)
{
if (wf2.ParentAssociation.Name.Equals("Nombre de tu workflow"))
{
ListI.Web.Site.WorkflowManager.RemoveWorkflowFromListItem(wf2);
}
}
try
{
Microsoft.SharePoint.Workflow.SPWorkflow instanceWF = site.WorkflowManager.StartWorkflow(ListI, WFA, WFA.AssociationData, true);
web.AllowUnsafeUpdates = false;
}
catch
{
}
finally
{
web.AllowUnsafeUpdates = false;
}

//**************

});
}


Basta con agregar este código para que se inicie automaticamente el workflow asociado al elemento.

Saludos

Enviar formularios de Infopath Form Services con usuario anónimo

Si queremos enviar un formulario de Infopath con un usuario anónimo, el formulario se debe enviar a través de un Web Services que se conecte a la biblioteca de documentos con una cuenta con privilegios de escritura en esa biblioteca.

Creamos un nuevo proyecto de Visual Studio 2005 (con 2008 no lo he hecho todavía), proyecto de C# de biblioteca de clases
El código es este:
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Workflow ;

namespace WebServiceAnonimo
{
[WebService(Namespace = "Aqui_tu_Namespace")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public void SubmitToFormLibrary(string siteName, string webName, string formLibraryName, string formName, string formXml)
{
SPSecurity.RunWithElevatedPrivileges(delegate
{
formName = formName.TrimEnd('.');
Microsoft.SharePoint.SPSite site = new Microsoft.SharePoint.SPSite(siteName + "/");
Microsoft.SharePoint.SPWeb web = site.OpenWeb(webName);
Microsoft.SharePoint.SPFolder folder = web.GetFolder(formLibraryName);
Microsoft.SharePoint.SPDocumentLibrary Library = (SPDocumentLibrary)web.Lists[formLibraryName];

web.AllowUnsafeUpdates = true;

UTF32Encoding encoder = new UTF32Encoding();
byte[] data = encoder.GetBytes(formXml);
folder.Files.Add(formName + ".xml", data, true);

});
}
}
}

Debemos publicar el web services en algún puerto distinto al que tengamos el MOSS.

Una vez hecho esto, debemos cambiar el método de envío de nuestro formulario de Infopath para que ahora sea a través de un web services. Abrimos el diseño del formulario de infopath, y creamos una conexión de envío del formulario que sea del tipo de Web Services.

Agregamos la dirección del web services y después seleccionamos la función.

Por último agregamos los valores de los parámetros del web services, que son:
Si la biblioteca de documentos asociada al formulario se encuentra en


http://localhost/Pruebas/Biblioteca


siteName --> Nombre del site, http://localhost/
webName --> Nombre del web, Pruebas
formLibraryName --> Nombre de la biblioteca, Biblioteca
formName --> Nombre con el que queremos que se almacene el formulario
formXML --> Aquí debemos marcar la opción de formulario completo


Es conveniente que estos datos se extraigan de etiquetas ocultar insertadas en el formulario

Pinchamos en siguiente y le damos un nombre a la conexión.
Ahora basta con asignar esta conexión con el método de envío del formulario (Herramientas --> Opciones de envio).

Saludos