view Agendas/trunk/src/Agendas.Web.Tests/AutorizationsTests.cs @ 183:212c664db5aa

Generalización del manejo de las acciones sobre eventos
author nelopauselli
date Mon, 08 Aug 2011 22:27:00 -0300
parents 1deccd6c3cb2
children a36a76bd6ec3
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using AltNetHispano.Agendas.Domain;
using AltNetHispano.Agendas.Web.Controllers;
using NUnit.Framework;

namespace Agendas.Web.Tests
{
	[TestFixture]
	public class Autorizaciones
	{
		private IEnumerable<MethodInfo> _methods;

		[TestFixtureSetUp]
		public void ReadMethods()
		{
			var types = typeof (HomeController).Assembly.GetTypes().ToList();
			var controllers = types.Where(t => typeof (Controller).IsAssignableFrom(t)).ToList();

			var methods = new List<MethodInfo>();
			foreach (var controller in controllers)
			{
				var temp =
					controller.GetMethods(BindingFlags.Public | BindingFlags.Instance | ~BindingFlags.FlattenHierarchy).Where(
						m => !m.IsPrivate && typeof (ActionResult).IsAssignableFrom(m.ReturnType));
				
				methods.AddRange(temp);
			}

			_methods = methods;
		}

		[Test]
		public void Acciones_publicas()
		{
			var acciones = new[]
			               	{
			               		"HomeController.Index", "HomeController.About", "EventoController.Index", "AccountController.LogOn",
			               		"AccountController.LogOff", "AccountController.TwitterLogOn", "HistoricoController.Index",
			               		"PersonaController.Index", "ErrorController.NoAutorizado"
			               	};

			#region Asserts

			bool fail = false;
			foreach (var method in _methods)
			{
				var action = method.DeclaringType.Name + "." + method.Name;
				if (acciones.Contains(action))
				{
					if (method.GetCustomAttributes(typeof (CustomAuthorizeAttribute), false).Any())
					{
						fail = true;
						Console.WriteLine(action + " debe ser público");
					}
				}
				else
				{
					if (!method.GetCustomAttributes(typeof (CustomAuthorizeAttribute), false).Any())
					{
						fail = true;
						Console.WriteLine(action + " debe ser seguro");
					}
				}
			}

			Assert.IsFalse(fail);

			#endregion
		}

		[Test]
		public void Acciones_privadas()
		{
			var acciones = new[]
			               	{
			               		"PerfilController.Index", "PerfilController.AddGoogleAccount", "PerfilController.AddTwitterAccount",
			               		"PerfilController.Remove", "PerfilController.Modificar"
			               	};

			VerficarAccionesSeguras(acciones, Roles.Usuario, "debe ser privado");
		}

		[Test]
		public void Acciones_del_administrador()
		{
			var acciones = new[]
			               	{
			               		"EventoController.Agendar", "EventoController.Confirmar", "EventoController.Nuevo",
			               		"EventoController.Publicar", "EventoController.Modificar", "EventoController.Proponer",
			               		"EventoController.Cancelar", "EventoController.Descartar", "EventoController.ReAgendar",
			               		"EventoController.ReProponer", "PersonaController.Nueva", "PersonaController.Modificar"
			               	};

			VerficarAccionesSeguras(acciones, Roles.Administrador, "debe ser de uso exclusivo de los administradores");
		}

		private void VerficarAccionesSeguras(IEnumerable<string> acciones, string rol, string mensaje)
		{
			bool fail = false;
			foreach (var method in _methods)
			{
				var action = method.DeclaringType.Name + "." + method.Name;
				if (acciones.Contains(action))
				{
					if (method.GetCustomAttributes(typeof (CustomAuthorizeAttribute), false).Any())
					{
						var found =
							method.GetCustomAttributesData().Any(d => d.NamedArguments.Any(a => rol.Equals(a.TypedValue.Value)));

						if (!found)
						{
							fail = true;
							Console.WriteLine(action + " " + mensaje);
						}
					}
					else
					{
						fail = true;
						Console.WriteLine(action + " debe ser seguro");
					}
				}
				else if (method.GetCustomAttributes(typeof (CustomAuthorizeAttribute), false).Any())
				{
					var found =
						method.GetCustomAttributesData().Any(d => d.NamedArguments.Any(a => rol.Equals(a.TypedValue.Value)));

					if (found)
					{
						fail = true;
						Console.WriteLine(action + " no " + mensaje);
					}
				}
			}
			Assert.IsFalse(fail);
		}
	}
}