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(); } 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(new[] {site}); var roles = new List(); 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 getRoles(SPSite site, string loginName) { var roles = new List(); 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().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 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(); } var roles = new List(); 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 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; } } }