sábado, 13 de marzo de 2010

Diferencia entre publicar un proyecto desde el servidor y desde Project Professional

En Project Server 2007 en el centro de proyectos hay una opción de editar las propiedades del proyecto y luego tiene un botón para hacer el guardar y publicar del proyecto pero que realmente guarda y publica únicamente las propiedades que permite modificar, como lo es el dueño del proyecto y la metadato asociada a el por medio de los campos personalizados.

Un caso curioso:

Se ha dado cuenta que cuando Ud. define un campo empresarial personalizado asociado al proyecto que es de tipo fórmula requiere de Project Professional para validar su sintaxis. Pues así mismo también requiere de Project Professional para estimar su valor por lo que no hay otra forma de actualizar su valor sino es  editando el proyecto y volviendo a publicar el proyecto desde Project Professional para que actualice el cálculo del campo de la fórmula esto nos lleva a la siguiente conclusión:

que realmente Project Server No calcula el valor sino lo almacena únicamente y solo se actualizará cada vez que lo publiquemos el proyecto desde Project Professional.

Project 4 fun!,

Manolo Herrera

viernes, 12 de marzo de 2010

Advertencia al Aplicar Net Framework 3.5 SP1 en SharePoint

Aunque ya había realizado la instalación del Net Framework 3.5 SP1 en diferentes clientes con instalaciones de SharePoint Server 2007 y no había tenido ningún inconveniente sucedió lo inesperado el look & Feel del sitio de SharePoint se distorsionó.

La instalación del Framework requiere que sea reiniciado el servidor de SharePoint por lo que lo hicimos y cuando volvió el portal presentaba el encabezado bastante mas abajo cuando el contenido era mayor al tamaño de la pantalla esto en IE 7 y 8. Pero adivine que en IE 6 si funcionaba, pero debería funcionar en todos los exploradores además por ser el navegador mas antiguo no tiene la definición de los estándares que si tienen IE 7 y 8.

Que descubrimos:

Bueno que la aplicación de estilos del portal estaban muy aplicados y que por todos lados tenia evidencia de parchar un estilo con otro. Pero porque antes no se reflejaba? bueno, no me queda mas que adivinar ya que no encontré mayor referencia al problema. El Framework 3.5 SP1 que reparo problemas con el diseñador Web de Visual Studio reforzó las reglas del html y esto evidencio la deficiencia del diseño del portal que se tenía pero que no había afectado hasta luego de instalarlo.

Que hicimos:

Corregir el css donde afectaba siguiendo las pitas que estilo estaba afectando y colocando el css de ultimo asegurándonos que no iba hacer reemplazando por otra regla de otro css dentro del la Master Page.

Conclusión:

Antes de aplicar el Framework 3.5 SP1 asegúrese de advertir las implicaciones de instalar el Framework y definir un tiempo y un experto diseñador para mitigar el riesgo y tener un plan de contingencia en caso de que esto suceda, Así como la ventana de mantenimiento para cubrir la corrección del mismo.

Otro consejo útil es que reinicie antes el servidor y advierta antes cualquier inconveniente que genere esta operación tan normal pero que en algunos casos no es efectuada y que puede evidenciar otros problemas o no.

Nota:

La razón de instalar el Net Framework 3.5 es que dentro del código del elemento Web instalado utilizaba el ensamblado System.Core.DLL donde esta el espacio de nombre System.Linq que utilice para manipular condiciones dentro de listas.

Code4Fun!, but be careful!,

Manolo Herrera

Cómo averiguar si el usuario conectado es Administrador en SharePoint

Aunque hay referencias del tema, son ejemplos incompletos o que no funcionan.  Abajo les describo lo que me funcionó y el cuidado que debe de tener con el código.

Primero lo primero obtener el usuario conectado al sitio a través de SPContext (es decir el contexto actual donde se esta ejecutando tu código).

SPUser usuarioActual = SPContext.Current.Web.CurrentUser;

Luego necesitamos obtener los Roles Asignados al sitio Actual para ello necesitamos la instancia el objeto SPWeb y ejecutar el código con privilegios de administrador para obtenerlo pero los objetos SPWeb obtenidos del contexto no se llevan bien por lo que obtendremos sus ID’s únicamente el GUID y no la referencia en memoria para luego ubicarlos con las siguientes líneas de código:

var IDSitio = SPContext.Current.Site.ID;
var IDWeb = SPContext.Current.Web.ID;

Ahora vamos con el código para obtener el Rol asignado al sitio del usuario:

using (SPSite miSitio = new SPSite(IDSitio))
                          {
                              using(SPWeb miWeb = miSitio.OpenWeb(IDWeb))
                              {
                                  SPRoleAssignment rol = miWeb.RoleAssignments.GetAssignmentByPrincipal(usuarioActual);
                                  if (rol != null)
                                  {
                                      SPRoleDefinitionBindingCollection roleDefBindings = rol.RoleDefinitionBindings;
                                      if (roleDefBindings != null)
                                      {
                                          foreach (SPRoleDefinition item in roleDefBindings)
                                          {
                                              if (item.Type == SPRoleType.Administrator)
                                              {
                                                  esAdministrador = true;
                                                  break;
                                              }
                                          }

                                      }

Si el usuario no tiene permisos específicos sobre este sitio aunque sea administrador de la colección de sitios devolverá falso. Así que para asegurarnos agregamos unas líneas mas:

if (!esAdministrador)
esAdministrador = usuarioActual.IsSiteAdmin;

Y para finalizar la nota curiosa de SharePoint, si el usuario no tiene full control o administrador no puede ejecutar este código y tirará una excepción tan solo la ejecutar esta línea de código:

SPRoleAssignment rol = miWeb.RoleAssignments.GetAssignmentByPrincipal(usuarioActual);

Entonces fuera del using defina un try catch de la siguiente forma:

try{

using….el resto del código

}catch(ArgumentException)
                      {

                          esAdministrador = false;
                      }

Para finalizar solo para optimizar el rendimiento del código utilizar el objeto session para una vez obtenido el valor almacenarlo allí para luego utilizarlo.

if (Session["UsuarioEsAdminsitrador"] == null)

Nota: SPRole esta obsoleto recomendado no utilizarlo, Visual Studio se lo indica inclusive.

Bueno los dejo con el código completo abajo. 

Happy & Secure Coding!,

Manolo Herrera

if (Session["UsuarioEsAdminsitrador"] == null)
            {
                bool esAdministrador = false;
                SPUser usuarioActual = SPContext.Current.Web.CurrentUser;
                var IDSitio = SPContext.Current.Site.ID;
                var IDWeb = SPContext.Current.Web.ID;
                SPSecurity.RunWithElevatedPrivileges(delegate
                  {
                      try
                      {
                          using (SPSite miSitio = new SPSite(IDSitio))
                          {
                              using (SPWeb miWeb = miSitio.OpenWeb(IDWeb))
                              {
                                  SPRoleAssignment rol = miWeb.RoleAssignments.GetAssignmentByPrincipal(usuarioActual);
                                  if (rol != null)
                                  {
                                      SPRoleDefinitionBindingCollection roleDefBindings = rol.RoleDefinitionBindings;
                                      if (roleDefBindings != null)
                                      {
                                          foreach (SPRoleDefinition item in roleDefBindings)
                                          {
                                              if (item.Type == SPRoleType.Administrator)
                                              {
                                                  esAdministrador = true;
                                                  break;
                                              }
                                          }
                                      }
                                      if (!esAdministrador)
                                          esAdministrador = usuarioActual.IsSiteAdmin;
                                  }
                              }
                          }
                      }
                      catch (ArgumentException)
                      {
                          esAdministrador = false;
                      }
                  });
                Session["UsuarioEsAdminsitrador"] = esAdministrador;
            }
            return Convert.ToBoolean(Session["UsuarioEsAdminsitrador"]);
            //Obsoleto
            //SPRoleCollection roles = usuarioActual.Roles;
            //if (roles != null)
            //{
            //    foreach (SPRole rol in roles)
            //    {
            //        if (rol.Type == SPRoleType.Administrator)
            //        {
            //            esAdministrador = true;
            //            break;
            //        }
            //    }
            //}

Hoja de estilos en librería da problemas de permisos en SharePoint

Contexto:

Los usuarios no administradores no tienen aplicados todos los estilos que si tienen los administradores de sitios y la hoja de estilos es obtenida de una librería dentro de SharePoint Específicamente “Style Library”.

Versión de SharePoint Server 2007 versión Enterprise

Plantilla de Sitio de Publicación

Hoja de estilos aplicada en la Master Page

Problema:

A pesar que los usuarios tengan permisos de lectura sobre la librería los estilos no son aplicados.

Solución:

Copiar en archivo de la hoja de estilos (css) a el directorio publico del servidor de SharePoint llamado images dentro de c:\program files\common files\web server extensions\12\template\images.

Luego hacer referencia en la Master Page de la hoja de estilos a la siguiente direccíón: /_layouts/images/[nombre de hoja de estilos.css].

Nota: [] utilizados para indicar debe de ser reemplazado el nombre. La negrita para resaltar lo que no varia.

Referencias:

Happy styling!,

Manolo Herrera

lunes, 8 de marzo de 2010

Diferencia entre SPContext.Current.FormContext.FormMode Y WebPartManager.DisplayMode en el Modelo de Objetos en SharePoint

Esto es muy útil cuando conocer cuando estamos escribiendo código personalizado para Elementos Web desde Visual Studio y necesitamos que se comporte de una forma cuando esta en modo de edición la página o el elemento Web especialmente cuando tengamos alguna animación o acción que nos afecta el editar la página para mantenimiento ya sea para modificar un valor de una propiedad de un elemento web.

SPContext.Current.FormContext.FormMode Este nos indica cuando está en modo de edición la página.  Ojo que si no es un sitio de publicación el modo de edición no se detecta hasta el momento de editar la página.  Los valores permitidos puede encontrarlos en el enumerador SPControlMode como se muestra en la imagen de abajo.

image

Cuando deseamos conocer el estado del Elemento Web del código que estamos desarrollando La propiedad DisplayMode del objeto WebPartManager.DisplayMode nos devuelve el estado actual del mismo entre los valores a retornar están:EditDisplayMode, BrowseDisplayMode, DesignDisplayMode que se obtienen del mismo objeto WebPartManager.

Un breve ejemplo de su uso:

 if (SPContext.Current.FormContext.FormMode != SPControlMode.Edit)
            {
                var sb = new StringBuilder("<script type='text/javascript'>");
                sb.Append("$(document).ready(function() {");
                sb.Append(string.Format("$('.{0}').vAlign();", ClaseEstilo));
                sb.Append(string.Format("$('.{0}').hAlign();", ClaseEstilo));
                sb.Append("});");
                sb.Append("</script>");
                Controls.Add(new LiteralControl { Text = sb.ToString() });
            }


En resumen el objeto SPFormContext nos devuelve el estado de la página y el objeto SPWebPartManager el del Elemento Web.



Code4Fun!,



Manolo Herrera

sábado, 6 de marzo de 2010

Error Access Denied al utilizar SPContext.Current.Web.Webs en SharePoint

Este error esta relacionado con SPContext y RunWithElevatedPrivileges.  SPContext debe de utilizarse a fuera del RunWithElevatedPrivileges y no se debe de utilizar el objeto SPWeb del contexto porque hará referencia al el nuevamente y nos indicará el error de acceso denegado en vez de ello utilice el ID que es de tipo GUID y a demás es más rápido para acceder los objetos SPSite y SPWeb.

Por último utilice la propiedad AllowUnsafeUpdates de los objetos SPSite y SPWeb dentro del código para indicar que no verifique los permisos de las operaciones que va a realizar.  No esta de mas recordarle la recomendación cuando instancia los objetos SPSite y SPWeb utilice using para que ejecute el método Dispose() cuando deje de utilizarlos y libere la memoria adecuadamente.

Nota: Siempre prefiero utilizar objetos livianos para manipular la información que deseo desplegar dentro de los elementos Web y así evitar el desperdicio de memoria que sucede cuando devolvemos un objeto de SharePoint.  Por ello usted verá en el ejemplo que devuelvo una lista de una clase llamada InformacionSitio.

Los dejo con el código abajo…Code4Fun!,

Manolo Herrera

 private IList<InformacionSitio> ObtenerInformacionSitio()
        {
            IList<InformacionSitio> listadoSitios = new List<InformacionSitio>();
            var idSitio = SPContext.Current.Site.ID;
            var idWeb = SPContext.Current.Web.ID;
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (SPSite miSitio = new SPSite(idSitio))
                {
                    miSitio.AllowUnsafeUpdates = true;
                    using (SPWeb miWeb = miSitio.OpenWeb(idWeb))
                    {
                        miWeb.AllowUnsafeUpdates = true;
                        foreach (SPWeb webActual in miWeb.Webs)
                        {
                            try
                            {
                                var sitioObtenido = _informacionSitioRepo.ObtenerSitio(this, webActual.Url, true);
                                if (sitioObtenido != null && sitioObtenido.Visible) listadoSitios.Add(sitioObtenido);
                            }
                            finally
                            {
                                if (webActual != null)
                                    webActual.Dispose();
                            }
                        }
                        miWeb.AllowUnsafeUpdates = false;
                    }
                    miSitio.AllowUnsafeUpdates = false;
                }
            });
            return listadoSitios;
        }

viernes, 5 de marzo de 2010

Semana Project Server 2007: Acerca de las TimeSheets o Parte de horas y el tiempo administrativo

Las TimeSheets son el repositorio para reportar el trabajo realizado durante un tiempo determinado (predeterminado una semana) tanto en Proyectos como en otras actividades de trabajo administrativo o de no trabajo dentro del horario laboral como es una enfermedad, o un permiso personal).

Dentro de Project Server el reportar el avance de las tareas es de preferencia utilizar las tareas asociadas al proyecto para reportar el avance y no una hoja tabular donde coloco el tiempo trabajado en ella.

Entonces podemos utilizar para el tiempo del proyecto las tareas y las TimeSheets para reportar el tiempo que no es de proyecto.

El tiempo administrativo que requiere autorización impedirá que la TimeSheet  sea enviada al adminsitrador de TimeSheets hasta que autorice dicho Tiempo Administrativo reportada dentro de la TimeSheet mostrando un indicador color amarillo y mostrando el mensaje que no puede ser enviada hasta que sea autorizado dicho Tiempo Administrativo. 

Nota: Predeterminadamente los recursos tiene asignado como Administrador de las TimeSheet esto eliminará el proceso de pre-autorizar antes de enviar la hoja administrativa y mucho menos autorizar la misma hoja ya que el mismo usuario que la llena es el que la autoriza.  Esto lo podemos cambiar en el Centro de Recursos o en la Administración de Usuarios.

Para finalizar el relato luego de enviada la Hoja de Tiempo si no ha sido autorizada una vez podemos seleccionar en Acciones la opción Recuperar la TimeSheet y esto como sucede con un correo en Outlook recupera la TimeSheet sin dejar rastro.  Si mas de una vez se autorizó la hoja igualmente podemos recuperarla para editarla y el administrador de la hoja tendrá la versión ultima que autorizó y cuando enviemos la nueva el decidirá si la Acepta o Rechaza.

Algo extremadamente importante para tomar en cuenta con las TimeSheets las horas reportadas allí influirá en el cronograma del  proyecto al abrir nuevamente le proyecto desde Project Professional correrá las fechas de las tareas que fueron afectadas por ese tiempo que reportamos que ocupamos en otra cosa que no fue la tarea.  Si deseáramos contrarrestar este efecto aunque sobre carguemos al recurso es en opciones avanzadas de la información de la tarea dentro de Project Professional utilicemos la opción Task Constraint  seleccionando la opción Must Finish on y la fecha que deseamos para que no corra la tarea afecta y regrese el cronograma a lo programado inicialmente.

Bueno espero aclarar algunos temas que solo a través de estos escenarios expuestos podemos descubrir su funcionamiento.

Hasta la próxima amigos!,

Manolo Herrera

Semana de Project Server 2007: Sabía Ud. que los permisos de Área de Trabajo de cada Proyecto es manejado por los permisos de Project Server

Recientemente me solicitaron que no se permitiera a todos los usuario a que consulte el área de trabajo de los proyectos, sino solo aquellos que se les autorizará.

Aclaración:  Antes de continuar debo aclarar que deberá el amigo lector tener experiencia configurando el Project Server ya que no describo paso a paso como hacerlo sino una explicación sobre el asunto.

La problemática y la solución esta en que todos los usuarios que tienen el permiso de “View Project Workspace”, cuando Project Server sincroniza los permisos de Project Server con las áreas de trabajo cada vez que:

  • Se crea un usuario.
  • Se activa un Usuario.
  • Se cambian los permisos de un usuario.
  • Se publica un proyecto.

Nota: Esto es cierto siempre y cuando tenga habilitada la opción predeterminada  "Automatically add Project Web Access users to project team Web site when SharePoint site is created or when the project manager publishes the project information to Project Server" dentro de la opción “Project Workspace Provisioning Settings” .

Qué hicimos? le quitamos a los grupos de Project Sever este permiso y adivine que solo los integrantes del grupo y jefes de proyecto podían verlo y algo mas respetando el RBS o EDR(Estructura Detallada de Recursos) que se aplican a las reglas de las categorías asociadas al grupo.

Otra cosa que descubrimos, y es que si agregamos a un proyecto otros integrantes que no tenga asignado alguna tarea le da permisos de Lectura sobre el proyecto una forma interesante de permitirle a un usuario en especifico como un stakeholder o interesado en el proyecto  para que pueda ver la información del área de trabajo del proyecto.

Otro descubrimiento fue que el permiso “Save Project to Project Server” que predeterminadamente lo tiene los Jefes de Proyecto y los Jefes de Cartera de Proyectos. Tiene el permisos en las áreas de trabajo Equivalente a Project Managers (Microsoft Office Project Server) a nivel de Sitio de SharePoint. que pueden crear Sub sitios como Áreas de reuniones disponibles dentro del evento de un calendario del área de trabajo.

Un escenario Especial solicitado fue el siguiente darle permisos a usuarios a una vista que accederán usuarios de otros departamentos interesados en un proyecto de un departamento en específico y que no pudieran ver el área de trabajo solo el cronograma es decir el centro de proyectos.  Que hicimos?

  • Crear una Plantilla de Seguridad.  (Para aplicar los permisos de la categoría y del grupo mas adelante solo con los necesarios para hacer logon y ver el centro de proyectos y ver el detalle del proyecto.)
  • Una Vista. (Para filtrar por medio de los campos personalizados empresariales asociados al proyecto el proyecto que pertenece al área que esta desarrollando el proyecto.)
  • Una categoría. (Para que no aplique los permisos del RBS o EDR sino todos los proyectos que contiene la vista, ya que los usuarios que vamos agregar pertenecerán a otros departamentos.) 
  • Un Grupo. (Que represente a los interesados en estos proyectos, asociando la categoría y aplicando la plantilla de seguridad  en la categoría asociada al grupo y a los permisos globales del grupo según la plantilla).

Como eliminamos el que pudieran ver el área de trabajo entonces aunque pueda ir al centro de proyectos y ver le proyecto al hacer clic sobre la opción Ir al Área de trabajo, le da un error de acceso denegado.  Si quisieran darle acceso al área de trabajo deberán entonces agregarlos al proyecto como miembros de equipo sin asignarle ninguna tarea.

Para finalizar con el tema indicarle que aquellos usuarios que por medio de un grupo tiene el permiso “Manage Windows SharePoint Services” en los permisos globales ellos tiene el equivalente a Web Administrator (Microsoft Office Project Server) que predeterminadamente están únicamente en los usuarios que pertenecen al grupo Administradores de Project Server.

Hasta la próxima!,

Manolo Herrera