Taylohtio/GeneralSSO/GeneralSSO.Server/CodeFiles/Services/Impl/RolesProvider.cs

260 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Microsoft.SharePoint;
using Taloyhtio.GeneralSSO.Server.CodeFiles.Common;
using Taloyhtio.GeneralSSO.Server.CodeFiles.Entities;
namespace Taloyhtio.GeneralSSO.Server.CodeFiles.Services.Impl
{
public class RoleNames
{
public const string Tenants = "asukkaat";
public const string Landlords = "osakkaat";
public const string BoardMembers = "hallitus";
public const string RegisteredTenants = "rekisteröityneet asukkaat";
public const string RegisteredLandlords = "rekisteröityneet osakkaat";
public const string PropertyManagers = "isännöitsijät";
}
public class RolesProvider : IRolesProvider
{
private const int CONDO_SITE_WEB_TEMPLATE_ID = 10101;
private const string CONDO_PREFIX = "as oy ";
private ILogger logger;
public RolesProvider()
{
this.logger = ServiceLocator.Current.GetInstance<ILogger>();
}
public UserRoles? GetRoles(SPSite site, string loginName)
{
if (string.IsNullOrEmpty(loginName))
{
return null;
}
SPUser user = null;
try
{
user = site.RootWeb.EnsureUser(loginName);
if (user == null)
{
this.logger.Error(Constants.LogComponents.RESOURCE_SERVER, string.Format("Can't calculate roles for user with login name '{0}': user not found", loginName));
return null;
}
}
catch (Exception x)
{
this.logger.Error(Constants.LogComponents.RESOURCE_SERVER, string.Format("Can't calculate roles for user with login name '{0}': exception is thrown\n{1}", loginName, x.ToInfo()));
return null;
}
//var sites = getSites(webApp, loginName);
var sites = new List<SPSite>(new[] {site});
var roles = new List<Role>();
sites.ForEach(s =>
{
var siteRoles = this.getRoles(s, loginName);
if (!siteRoles.IsNullOrEmpty())
{
roles.AddRange(siteRoles);
}
});
string email = this.getEmail(user, roles);
return new UserRoles(email, roles.ToArray());
}
private List<Role> getRoles(SPSite site, string loginName)
{
var roles = new List<Role>();
SPSecurity.RunWithElevatedPrivileges(
() =>
{
try
{
using (var elevatedSite = new SPSite(site.ID, site.Zone))
{
// check property manager group first - it should be returned only once for root web
var propertyManagersGroup = elevatedSite.RootWeb.SiteGroups.Cast<SPGroup>().FirstOrDefault(g => g.Name.EndsWith(string.Format("{0} - Isännöitsijät", site.RootWeb.Title)));
if (propertyManagersGroup != null && this.isMember(propertyManagersGroup, loginName))
{
roles.Add(new Role(site.RootWeb.ID, site.RootWeb.Url, RoleNames.PropertyManagers, false, string.Empty));
}
// then condos
foreach (SPWeb web in elevatedSite.RootWeb.GetSubwebsForCurrentUser(/*CONDO_SITE_WEB_TEMPLATE_ID*/))
{
try
{
var webRoles = this.getRoles(web, loginName);
if (!webRoles.IsNullOrEmpty())
{
roles.AddRange(webRoles);
}
}
finally
{
web.Dispose();
}
}
}
}
catch (Exception x)
{
this.logger.Error(Constants.LogComponents.RESOURCE_SERVER, string.Format("Error occured during retrieving user roles:\n{0}\n{1}", x.Message, x.StackTrace));
throw;
}
});
return roles;
}
private List<Role> getRoles(SPWeb web, string loginName)
{
// check only condo sites
if (web.WebTemplateId != CONDO_SITE_WEB_TEMPLATE_ID && !web.Title.ToLower().StartsWith(CONDO_PREFIX.ToLower()))
{
return new List<Role>();
}
var roles = new List<Role>();
foreach (SPGroup g in web.Groups)
{
if (this.isMember(g, loginName))
{
string roleName = this.getRoleName(web, g.Name);
if (!string.IsNullOrEmpty(roleName))
{
roles.Add(new Role(web.ID, web.Url, roleName, true, this.getCondoShortName(web)));
}
}
}
return roles;
}
// General users (general tenants and landlords) have the same predefined email, but they should be
// distinguished somehow by Pelsu. For such users return speciail formated not real email
private string getEmail(SPUser user, List<Role> roles)
{
if (user == null)
{
return string.Empty;
}
if (string.Compare(user.Email, Constants.Users.GENERAL_USER_EMAIL, true) != 0)
{
return user.Email;
}
// get role for first condo, where current user is general tenant or general landlord
var generalUserRoles = roles.Where(r => r.IsCondo && (this.isGeneralTenant(user.LoginName, r.CondoShortName) || this.isGeneralLandlord(user.LoginName, r.CondoShortName)));
if (generalUserRoles.IsNullOrEmpty())
{
return user.Email;
}
var role = generalUserRoles.First();
if (this.isGeneralTenant(user.LoginName, role.CondoShortName))
{
return string.Format(Constants.Users.GENERAL_TENANT_EMAIL_TEMPLATE, role.WebId);
}
else if (this.isGeneralLandlord(user.LoginName, role.CondoShortName))
{
return string.Format(Constants.Users.GENERAL_LANDLORD_EMAIL_TEMPLATE, role.WebId);
}
return user.Email;
}
private bool isGeneralTenant(string loginName, string condoShortName)
{
if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(condoShortName))
{
return false;
}
string generalTenantName = condoShortName.ToLower();
return this.isGeneralUser(loginName, generalTenantName);
}
private bool isGeneralLandlord(string loginName, string condoShortName)
{
if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(condoShortName))
{
return false;
}
string generalLandlordName = string.Format(Constants.Users.GENERAL_LANDLORD_NAME_TEMPLATE, condoShortName).ToLower();
return this.isGeneralUser(loginName, generalLandlordName);
}
private bool isGeneralUser(string loginName, string generalUserName)
{
if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(generalUserName))
{
return false;
}
loginName = loginName.ToLower();
generalUserName = string.Format(":{0}", generalUserName).ToLower();
// fba user names have the following format: {membership provider name}:{login name}
return loginName.EndsWith(generalUserName);
}
private string getCondoShortName(SPWeb web)
{
if (web.AllProperties.ContainsKey(Constants.Condo.SHORT_NAME))
{
return web.AllProperties[Constants.Condo.SHORT_NAME] as string;
}
if (web.Title.ToLower().StartsWith(CONDO_PREFIX.ToLower()))
{
return web.Title.Substring(CONDO_PREFIX.Length);
}
return string.Empty;
}
private bool isMember(SPGroup group, string loginName)
{
foreach (SPUser user in group.Users)
{
if (string.Compare(user.LoginName, loginName, false) == 0)
{
return true;
}
}
return false;
}
private string getRoleName(SPWeb web, string groupName)
{
if (groupName.IsNullOrEmpty())
{
return string.Empty;
}
if (groupName.EndsWith(string.Format("{0} - Asukkaat", web.Title)))
{
return RoleNames.Tenants;
}
if (groupName.EndsWith(string.Format("{0} - Osakkaat", web.Title)))
{
return RoleNames.Landlords;
}
if (groupName.EndsWith(string.Format("{0} - Hallitus", web.Title)))
{
return RoleNames.BoardMembers;
}
if (groupName.EndsWith(string.Format("{0} - Rekisteröityneet asukkaat", web.Title)))
{
return RoleNames.RegisteredTenants;
}
if (groupName.EndsWith(string.Format("{0} - Rekisteröityneet osakkaat", web.Title)))
{
return RoleNames.RegisteredLandlords;
}
return string.Empty;
}
}
}