viernes, 28 de octubre de 2011

Comprendiendo el registro de usuarios dentro de SharePoint 2010

Para comprender como funciona el registro de usuarios dentro de SharePoint es importante declarar algunas cosas como las que siguen:

En la jerarquía de objetos primaria de contenido de SharePoint  podemos decir que todos los objetos están dentro de una Web Application (SPWebApplication). La Web Application tiene por lo menos una o mas base de datos de contenido. Cada base de datos de contenido puede tener una o mas colecciones de sitio (SPSite) y una colección de sitios puede tener por lo menos un sitio primario (SPWeb) y muchos subsitios (SPWeb) que puede a su vez contener mas subsitios. Dentro de los subsitios podemos hallar una lista (SPList) o  biblioteca de SharePoint y esta contiene un o mas elementos (SPListItem) y cada elemento puede contener uno o mas campos(SPField).  Esto se puede apreciar en la siguiente imagen:

PrimaryObjectsContentHierarchy

La regla

Cuando un usuario es:

1) Registrado dentro de un grupo de SharePoint 

2) Concedido permiso a un usuario directamente en algún sitio

3) O el usuario a subido un documento o agregado un elemento.

Este es internamente registrado en una tabla de base de datos llamada UserInfo de la base de datos de contenido a la que pertenece la Web Application. Esto lo hace por cada colección de sitios.  Esto quiere decir que si existen varias colecciones de sitios dentro de la misma base de datos que solamente tiene una única tabla UserInfo entonces encontraremos varios registros del mismo usuario dentro de dicha tabla ya que cada registro representará el usuario dentro de cada colección de sitios, como se muestra en la imagen de abajo.

image

Pero no toda esta información esta disponible a través de una la lista de SharePoint llamada "User Information List".  Para los mortales no tenemos acceso a la columna SystemID o SID, vía el modelo de objetos de SharePoint. 

Otra cosa importante a notar es que a pesar que la SharePoint Server tiene disponible los perfiles de los usuarios del directorio Activo.  El primero verifica al usuario en la tabla UserInfo.  Por ejemplo cuando accedemos el objecto SPUSer esta información la va a traer a UserInfo, cuando utilizamos el control PeoplePicker la información la va a traer primero a UserInfo y luego verifica el Directorio Activo.  Cuando utilizamos SPContext.Current.Web.CurrentUser para obtener el usuario que esta conectado va directamente a los registros de UserInfo.

El problema:

Supongamos que dispusimos que todos los usuarios tengan acceso de lectura al portal y agregamos en lectores o visitantes a los domain users del Directorio Activo.  Sucede que estos usuarios no aparecerán en la tabla UserInfo hasta que el usuario suba un documento (donde tenga permisos obviamente) o algún administrador de sitio agregue puntualmente al usuario a un grupo de SharePoint o le de permisos del sitio específicamente a este usuario.  Y recuerde que este es cierto para cada colección de sitios.  Es decir puede estar registrado en una colección de sitios y en otra no, y si hubo un cambio en la información del usuario en la ultima colección de sitios registrado este usuario se verá actualizado.  

Lo que es mas serio aún es que la información de la cuenta del usuario no se modifica sino que se queda como originalmente se registro la primera vez en SharePoint en la tabla UserInfo.  La demás información como correo, nombre completo, teléfono de trabajo se encarga para la versión SharePoint Server de sincronizarla con los perfiles de usuario. Pero si en el directorio activo se cambia ya sea el nombre de la cuenta del usuario o el dominio, este cambio nunca se reflejará en la tabla UserInfo de los registros de SharePoint. 

Y el problema esta cuando queremos comparar por cuenta de dominio del usuario (que si lo tenemos disponible) la información que registra SharePoint con la información de los perfiles de usuario para obtener alguna propiedad personalizada como lo puede ser el código de empleado. No encontraremos al usuario aunque sea el mismo, entonces una solución alternativa es acceder directamente las bases de datos vía comando T-SQL comparando los SID de ambas tablas.

El comando es el siguiente:

  SELECT TOP 1000
       up.[RecordID]
      ,up.[DocID]
      ,up.[UserID]
      ,up.[NTName]
      ,up.[PreferredName]
      ,up.[Email]
      ,up.[SID]
      ,up.[Manager]
      ,up.[SipAddress]
      ,up.[LastUpdate]
      ,up.[LastUserUpdate]
      ,up.[LastImported]
      ,up.[bDeleted]
      ,up.[DataSource]
      ,up.[MasterRecordID]
      ,up.[ProfileSubtypeID]
      ,up.[DSGuid]
      ,up.[DNId]
      ,up.[PictureUrl]
      ,up.[PartitionID]
      ,ui.[tp_SiteID]
      ,ui.[tp_ID]
      ,ui.[tp_DomainGroup]
      ,ui.[tp_SystemID]
      ,ui.[tp_Deleted]
      ,ui.[tp_SiteAdmin]
      ,ui.[tp_IsActive]
      ,ui.[tp_Login]
      ,ui.[tp_Title]
      ,ui.[tp_Email]
      ,ui.[tp_Notes]
      ,ui.[tp_Token]
      ,ui.[tp_ExternalToken]
      ,ui.[tp_ExternalTokenLastUpdated]
      ,ui.[tp_Locale]
      ,ui.[tp_CalendarType]
      ,ui.[tp_AdjustHijriDays]
      ,ui.[tp_TimeZone]
      ,ui.[tp_Time24]
      ,ui.[tp_AltCalendarType]
      ,ui.[tp_CalendarViewOptions]
      ,ui.[tp_WorkDays]
      ,ui.[tp_WorkDayStartHour]
      ,ui.[tp_WorkDayEndHour]
      ,ui.[tp_Mobile]
      ,ui.[tp_Flags]
  FROM [User Profile Service Application_ProfileDB_123205d384044ee8a656082df38f38b2].[dbo].[UserProfile_Full] as UP,
  [WSS_Content].[dbo].[UserInfo] UI
  where UP.SID = UI.tp_systemid

Con esto podremos obtener la información del mismo usuario de las dos tablas.  Tomar nota que el nombre de las bases de datos pueden variar dependiendo de su instalación. Tiene que averiguar el nombre de la base de datos de Perfiles de Usuario y la de Contenido del portal o donde esta la colección de sitios desea.

En este artículo se explicó sobre algunos aspectos no muy claros pero importantes sobre los usuarios como se registran en SharePoint especialmente cuando desarrollamos aplicaciones para SharePoint 2010 y en 2007 es lo mismo.

SharePoint4Fun!,

Juan Manuel Herrera O.

No hay comentarios.: