Taylohtio/FBAUsersSearch/CustomFBADataSource/Layouts/Taloyhtio/FBA/sitecolls.ashx.cs

236 lines
9.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Security;
using CamlexNET;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Taloyhtio.CustomFBADataSource.CodeFiles;
namespace Taloyhtio.CustomFBADataSource
{
public class sitecolls : IHttpHandler
{
private const string QUERY_STRING_KEY_USER_NAME = "UserName";
private const string QUERY_STRING_KEY_OP = "op";
private const string QUERY_STRING_KEY_OP_NEW = "new";
private const string QUERY_STRING_KEY_OP_OLD = "old";
public void ProcessRequest(HttpContext context)
{
try
{
var web = SPContext.Current.Web;
if (web.CurrentUser == null || !web.CurrentUser.IsSiteAdmin)
{
throw new Exception("Current user is not site admin");
}
string userName = context.Request.QueryString[QUERY_STRING_KEY_USER_NAME];
if (string.IsNullOrEmpty(userName))
{
throw new Exception("User name is empty");
}
userName = HttpUtility.UrlDecode(userName);
string op = context.Request.QueryString[QUERY_STRING_KEY_OP];
if (string.IsNullOrEmpty(op))
{
throw new Exception("Operation is empty");
}
op = op.ToLower();
if (op != QUERY_STRING_KEY_OP_NEW && op != QUERY_STRING_KEY_OP_OLD)
{
throw new Exception("Operation is not supported");
}
var siteColls = new List<string>();
if (op == QUERY_STRING_KEY_OP_NEW)
{
// currently new algorithm can be used only for Taloytio
if (this.isTaloyhtio())
{
siteColls = this.getSiteCollectionsUsingNewMethod(userName);
}
}
else if (op == QUERY_STRING_KEY_OP_OLD)
{
siteColls = this.getSiteCollectionsUsingOldMethod(userName);
}
this.sendResponse(context, siteColls, false, string.Empty);
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception x)
{
this.sendError(context, x.Message);
}
}
private List<string> getSiteCollectionsUsingNewMethod(string userName)
{
try
{
var result = new List<string>();
// run code under elevated priveleges in order to connect to db using account of application pool. In this case we need
// to grant permissions to db only to single account, not to all users under which this code will be executed
SPSecurity.RunWithElevatedPrivileges(
() =>
{
string url = string.Empty;
using (var rootSite = new SPSite(SPContext.Current.Site.WebApplication.Sites[0].ID, SPContext.Current.Site.Zone))
{
url = rootSite.Url;
}
if (string.IsNullOrEmpty(userName))
{
return;
}
string connStr = this.getConnectionString();
if (string.IsNullOrEmpty(connStr))
{
return;
}
var r = new CredentialsRepository(connStr);
var userId = r.GetUserId(userName);
if (userId == Guid.Empty)
{
return;
}
var condos = r.GetUserCondos(userId);
if (condos.IsNullOrEmpty())
{
return;
}
result = condos.Select(c => SPUrlUtility.CombineUrl(url, c.PmcRelativeUrl)).Distinct().ToList();
});
return result;
}
catch (Exception x)
{
this.log("Error occured in new method (user name '{0}'): {1}\n{2}", userName, x.Message, x.StackTrace);
return new List<string>();
}
}
private string getConnectionString()
{
string connStringName = this.isTaloyhtio() ? Constants.FBA_CONNECTION_STRING_TALOYHTIO : Constants.FBA_CONNECTION_STRING_TALLIER;
if (ConfigurationManager.ConnectionStrings == null || ConfigurationManager.ConnectionStrings[connStringName] == null)
{
return string.Empty;
}
return ConfigurationManager.ConnectionStrings[connStringName].ConnectionString;
}
private bool isTaloyhtio()
{
string url = SPContext.Current.Site.Url.ToLower();
return url.Contains("taloyhtio");
}
private List<string> getSiteCollectionsUsingOldMethod(string userName)
{
var siteColls = new List<string>();
try
{
SPSecurity.RunWithElevatedPrivileges(
() =>
{
string url = string.Empty;
using (var rootSite = new SPSite(SPContext.Current.Site.WebApplication.Sites[0].ID, SPContext.Current.Site.Zone))
{
url = rootSite.Url;
}
using (var elevatedSite = new SPSite(SPContext.Current.Site.ID, SPContext.Current.Site.Zone))
{
var settings = Utils.GetFBAIisSettings(elevatedSite);
if (settings == null)
{
this.log("FBA IIS settings can't be retrieved");
return;
}
var membershipProvider = Membership.Providers[settings.FormsClaimsAuthenticationProvider.MembershipProvider];
string prefixOld = membershipProvider.Name.ToLower() + ":";
string prefixClaims = "i:0#.f|" + membershipProvider.Name.ToLower() + "|";
var sites = elevatedSite.WebApplication.Sites;
foreach (SPSite site in sites)
{
if (this.userBelongsToSite(prefixClaims, prefixOld, userName, site))
{
siteColls.Add(SPUrlUtility.CombineUrl(url, site.ServerRelativeUrl));
}
}
}
});
return siteColls;
}
catch (Exception x)
{
this.log("Error occured in old method (user name '{0}'): {1}\n{2}", userName, x.Message, x.StackTrace);
return new List<string>();
}
}
private void sendError(HttpContext context, string error)
{
this.sendResponse(context, new List<string>(), true, error);
}
private void sendResponse(HttpContext context, List<string> siteColls, bool isError, string error)
{
var response = context.Response;
response.Clear();
var s = new JavaScriptSerializer();
string result = s.Serialize(new { SiteColls = siteColls, IsError = isError, ErrorMessage = error });
response.ContentType = "application/json";
response.Write(result);
response.Flush();
response.End();
}
private bool userBelongsToSite(string prefixClaims, string prefixOld, string userName, SPSite site)
{
if (string.IsNullOrEmpty(userName) || site == null)
{
return false;
}
var query = new SPQuery();
query.Query = Camlex.Query().Where(x => ((string)x["Name"] == prefixClaims + userName || (string)x["Name"] == prefixOld + userName) && (string)x["ContentType"] == "Person").ToString();
//query.ViewFields = Camlex.Query().ViewFields(x => new[] { x["Name"] });
var itemsCount = site.RootWeb.SiteUserInfoList.GetItems(query).Count;
return (itemsCount > 0);
}
public bool IsReusable
{
get { return true; }
}
private void log(string msg, params object[] args)
{
try
{
msg = string.Format(msg, args);
msg = string.Format("{0} (thread id: {1})\t{2}\n", DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss"), Thread.CurrentThread.ManagedThreadId, msg);
File.AppendAllText(string.Format("c://temp/_fbauserssearch_{0}.txt", isTaloyhtio() ? "taloyhtio" : "tallier"), msg);
}
catch { }
}
}
}