public static string ExplainOrigin(this Revision revision, User user) { string relationship = "initial version"; int userId = user.IsAnonymous ? 0 : user.Id; if (revision.Parent != null) { if (revision.Parent.OwnerId != userId) { relationship = "forked from"; if (revision.Parent != null) { relationship += " " + revision.Parent.Owner.Login + "'" + (!revision.Parent.Owner.Login.EndsWith("s") ? "s" : ""); } } else { relationship = "created from your"; } relationship += " revision " + revision.Parent.Id; } return "revision " + revision.Id + ", " + relationship; }
public static void EnsureSafe(NameValueCollection form, User CurrentUser) { string xsrfFormValue = form["fkey"]; if (xsrfFormValue.IsNullOrEmpty()) throw new InvalidOperationException("XSRF validation: Request did not have required form value 'fkey'"); if (!xsrfFormValue.Equals(CurrentUser.XSRFFormValue, StringComparison.OrdinalIgnoreCase)) throw new InvalidOperationException( "XSRF validation: Request form value 'fkey' did not match CurrentUser.XSRFFormValue"); Debug.WriteLine("XSRFSafeAttribute.EnsureSafe => true"); }
public ActionResult Edit(int id, User updatedUser) { User user = Current.DB.Users.Get(id); if (updatedUser.DOB < DateTime.UtcNow.AddYears(-100) || updatedUser.DOB > DateTime.UtcNow.AddYears(-6)) { updatedUser.DOB = null; } if (user.Id == updatedUser.Id && (updatedUser.Id == CurrentUser.Id || CurrentUser.IsAdmin)) { var violations = updatedUser.GetBusinessRuleViolations(ChangeAction.Update); if (violations.Count == 0) { var snapshot = Snapshotter.Start(user); user.Login = HtmlUtilities.Safe(updatedUser.Login); user.AboutMe = updatedUser.AboutMe; user.DOB = updatedUser.DOB; user.Email = HtmlUtilities.Safe(updatedUser.Email); user.Website = HtmlUtilities.Safe(updatedUser.Website); user.Location = HtmlUtilities.Safe(updatedUser.Location); // Preferences are updated separately, so we should likely do this elsewhere instead... // Can likely move it out if we have introduce a fancier OpenID management panel like // the network has. user.EnforceSecureOpenId = updatedUser.EnforceSecureOpenId; var diff = snapshot.Diff(); if (diff.ParameterNames.Any()) { Current.DB.Users.Update(user.Id, snapshot.Diff()); } return Redirect("/users/" + user.Id); } else { foreach (var violation in violations) ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage); return Edit(user.Id); } } else { return Redirect("/"); } }
public ActionResult Edit(int id, User updatedUser) { User user = Current.DB.Users.First(u => u.Id == id); if (updatedUser.DOB < DateTime.Now.AddYears(-100) || updatedUser.DOB > DateTime.Now.AddYears(-6)) { updatedUser.DOB = null; } if (user.Id == updatedUser.Id && (updatedUser.Id == CurrentUser.Id || CurrentUser.IsAdmin)) { var violations = updatedUser.GetBusinessRuleViolations(ChangeAction.Update); if (violations.Count == 0) { user.Login = HtmlUtilities.Safe(updatedUser.Login); user.AboutMe = updatedUser.AboutMe; user.DOB = updatedUser.DOB; user.Email = HtmlUtilities.Safe(updatedUser.Email); user.Website = HtmlUtilities.Safe(updatedUser.Website); user.Location = HtmlUtilities.Safe(updatedUser.Location); Current.DB.SubmitChanges(); return Redirect("/users/" + user.Id); } else { foreach (var violation in violations) ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage); return Edit(user.Id); } } else { return Redirect("/"); } }
public static QueryResults ExecuteNonCached(ParsedQuery query, Site site, User user) { var remoteIP = OData.GetRemoteIP(); var key = "total-" + remoteIP; var currentCount = (int?)Current.GetCachedObject(key) ?? 0; currentCount++; Current.SetCachedObjectSliding(key, currentCount, 60 * 60); if (currentCount > 130) { // clearly a robot, auto black list var b = new BlackList { CreationDate = DateTime.UtcNow, IPAddress = remoteIP }; } if (currentCount > 100) { throw new Exception("You can not run any new queries for another hour, you have exceeded your limit!"); } if (Current.DB.ExecuteQuery<int>("select count(*) from BlackList where IPAddress = {0}", remoteIP).First() > 0) { System.Threading.Thread.Sleep(2000); throw new Exception("You have been blacklisted due to abuse!"); } var results = new QueryResults(); using (SqlConnection cnn = site.GetConnection()) { cnn.Open(); // well we do not want to risk blocking, if somebody needs to change this we will need to add a setting cnn.Execute("set transaction isolation level read uncommitted"); var timer = new Stopwatch(); timer.Start(); var messages = new StringBuilder(); var infoHandler = new SqlInfoMessageEventHandler((sender, args) => { // todo handle errors as well messages.AppendLine(args.Message); }); try { cnn.InfoMessage += infoHandler; if (query.IncludeExecutionPlan) { using (var command = new SqlCommand("SET STATISTICS XML ON", cnn)) { command.ExecuteNonQuery(); } } var plan = new QueryPlan(); foreach (string batch in query.ExecutionSqlBatches) { using (var command = new SqlCommand(batch, cnn)) { command.CommandTimeout = QUERY_TIMEOUT; PopulateResults(results, command, messages, query.IncludeExecutionPlan); } if (query.IncludeExecutionPlan) { plan.AppendBatchPlan(results.ExecutionPlan); results.ExecutionPlan = null; } } results.ExecutionPlan = plan.PlanXml; } finally { cnn.InfoMessage -= infoHandler; results.Messages = messages.ToString(); } timer.Stop(); results.ExecutionTime = timer.ElapsedMilliseconds; ProcessMagicColumns(results, cnn); } return results; }
public static User CreateUser(string accountLogin) { var u = new User { CreationDate = DateTime.UtcNow, Login = accountLogin, ADLogin = accountLogin, }; u.Id = Current.DB.Users.Insert(new { u.Login, u.ADLogin, u.CreationDate }).Value; return u; }
private static QueryResults GetSingleSiteResults(ParsedQuery query, Site site, User user, AsyncQueryRunner.AsyncResult result = null) { QueryResults results = null; var timer = new Stopwatch(); timer.Start(); var cache = QueryUtil.GetCachedResults(query, site.Id); if (cache != null) { if (!query.IncludeExecutionPlan || cache.ExecutionPlan != null) { results = new QueryResults(); results.WithCache(cache); results.Truncated = cache.Truncated; results.Messages = cache.Messages; results.FromCache = true; // If we didn't ask for the execution plan, don't return it if (!query.IncludeExecutionPlan) { results.ExecutionPlan = null; } } } timer.Stop(); if (results == null) { results = ExecuteNonCached(query, site, user, result); results.FromCache = false; // Don't cache cancelled results, since we don't know what state they're in... if (result != null && !result.Cancelled) { AddResultToCache(results, query, site, cache != null); } } else { results.ExecutionTime = timer.ElapsedMilliseconds; } results.Url = site.Url; results.SiteId = site.Id; results.SiteName = site.Name.ToLower(); return results; }
public static QueryResults ExecuteNonCached(ParsedQuery query, Site site, User user, AsyncQueryRunner.AsyncResult result) { var remoteIP = OData.GetRemoteIP(); var key = "total-" + remoteIP; var currentCount = (int?)Current.GetCachedObject(key) ?? 0; currentCount++; Current.SetCachedObjectSliding(key, currentCount, 60 * 60); if (currentCount > 130) { // clearly a robot, auto black list Current.DB.BlackList.Insert(new { CreationDate = DateTime.UtcNow, IPAddress = remoteIP }); } if (currentCount > 100) { throw new Exception("You can not run any new queries for another hour, you have exceeded your limit!"); } if (Current.DB.Query<int>("select count(*) from BlackList where IPAddress = @remoteIP", new { remoteIP }).First() > 0) { System.Threading.Thread.Sleep(2000); throw new Exception("You have been blacklisted due to abuse!"); } var results = new QueryResults(); using (SqlConnection cnn = site.GetOpenConnection()) { // well we do not want to risk blocking, if somebody needs to change this we will need to add a setting cnn.Execute("set transaction isolation level read uncommitted"); var timer = new Stopwatch(); timer.Start(); var messages = new StringBuilder(); var infoHandler = new SqlInfoMessageEventHandler((sender, args) => { // todo handle errors as well messages.AppendLine(args.Message); }); try { cnn.InfoMessage += infoHandler; if (query.IncludeExecutionPlan) { using (var command = new SqlCommand("SET STATISTICS XML ON", cnn)) { command.ExecuteNonQuery(); } } var plan = new QueryPlan(); foreach (string batch in query.ExecutionSqlBatches) { using (var command = new SqlCommand(batch, cnn)) { if (result != null) { result.Command = command; if (result.Cancelled) { continue; } } command.CommandTimeout = AppSettings.QueryTimeout; try { PopulateResults(results, command, result, messages, query.IncludeExecutionPlan); } catch (Exception ex) { // Ugh. So, if we cancel the query in-process, we get an exception... // But we have no good way of knowing that the exception here is actually // *that* exception...so we'll just assume it was if the state is Cancelled if (result == null || result.State != AsyncQueryRunner.AsyncState.Cancelled) { throw ex; } } } if (query.IncludeExecutionPlan) { plan.AppendBatchPlan(results.ExecutionPlan); results.ExecutionPlan = null; } } results.ExecutionPlan = plan.PlanXml; } finally { cnn.InfoMessage -= infoHandler; results.Messages = messages.ToString(); } timer.Stop(); results.ExecutionTime = timer.ElapsedMilliseconds; ProcessMagicColumns(results, cnn); } return results; }
private int? FindUserId(User user) { if (!user.IsAnonymous && user.Email != null) { using (var cnn = GetOpenConnection()) { string hash = Util.GravatarHash(user.Email); try { return cnn.Query<int?>("select top 1 Id from Users where EmailHash = @hash order by Reputation desc", new {hash}).FirstOrDefault(); } catch { // allow this to fail, its not critical } } } return null; }
public static User CreateUser(string login, string email, string openIdClaim) { var u = new User(); u.CreationDate = DateTime.UtcNow; login = CleanLogin(login ?? string.Empty); if (login.Length == 0) { login = emptyLogin; } u.Login = login; u.Email = email; int retries = 0; bool success = false; int maxId = Current.DB.Query<int?>("select max(Id) + 1 from Users").First() ?? 0; maxId += 1; while (!success) { IList<BusinessRuleViolation> violations = u.GetBusinessRuleViolations(ChangeAction.Insert); if (violations.Any(v => v.PropertyName == "Login")) { u.Login = login + (maxId + retries); } else if (violations.Count > 0) { throw new NotImplementedException("The User isn't valid, and we can't compensate for it right now."); } else { success = true; } } u.Id = Current.DB.Users.Insert(new { u.Email, u.Login, u.CreationDate }).Value; Current.DB.UserOpenIds.Insert(new { OpenIdClaim = openIdClaim, UserId = u.Id }); return u; }
/// <summary> /// initializes current user based on the current Request's cookies/authentication status. This /// method could return a newly created, Anonymous User if no means of identification are found. /// </summary> protected void InitCurrentUser() { _currentUser = new User(); _currentUser.IsAnonymous = true; if (Request.IsAuthenticated) { int id; if (Int32.TryParse(User.Identity.Name, out id)) { User lookup = Current.DB.Users.FirstOrDefault(u => u.Id == id); if (lookup != null) { _currentUser = lookup; _currentUser.IsAnonymous = false; } } else { FormsAuthentication.SignOut(); } } _currentUser.IPAddress = Request.UserHostAddress; }
partial void DeleteUser(User instance);
partial void UpdateUser(User instance);
partial void InsertUser(User instance);
private int? FindUserId(User user) { if (!user.IsAnonymous && user.Email != null) { using (SqlConnection cnn = GetConnection()) { string hash = Util.GravatarHash(user.Email); cnn.Open(); SqlCommand cmd = cnn.CreateCommand(); cmd.CommandText = "select top 1 Id from Users where EmailHash = @EmailHash order by Reputation desc"; SqlParameter p = cmd.Parameters.Add("@EmailHash", SqlDbType.NVarChar); p.Value = hash; try { return (int?)cmd.ExecuteScalar(); } catch { // allow this to fail, its not critical } } } return null; }
/// <summary> /// initializes current user based on the current Request's cookies/authentication status. This /// method could return a newly created, Anonymous User if no means of identification are found. /// </summary> protected void InitCurrentUser() { _currentUser = GetCurrentUser(Request, User.Identity.Name); }
private static User GetCurrentUser(bool isAuthenticated, string userHostAddress, string identity) { var user = new User(); user.IsAnonymous = true; if (isAuthenticated) { int id; if (Int32.TryParse(identity, out id)) { User lookup = Current.DB.Users.Get(id); if (lookup != null) { user = lookup; user.IsAnonymous = false; } } else { FormsAuthentication.SignOut(); } } user.IPAddress = userHostAddress; return user; }
public static User CreateUser(string login, string email, string openIdClaim) { var u = new User(); u.CreationDate = DateTime.UtcNow; login = CleanLogin(login ?? string.Empty); if (login.Length == 0) { /* email scrubbing got people upset, so it is gone now if (email != null) login = CleanLogin(email.Split('@')[0]); */ if (login.Length == 0) login = emptyLogin; } u.Login = login; u.Email = email; int retries = 0; bool success = false; int maxId = Current.DB.ExecuteQuery<int?>("select max(Id) + 1 from Users").First() ?? 0; maxId += 1; while (!success) { IList<BusinessRuleViolation> violations = u.GetBusinessRuleViolations(ChangeAction.Insert); if (violations.Any(v => v.PropertyName == "Login")) { u.Login = login + (maxId + retries); } else if (violations.Count > 0) { throw new NotImplementedException("The User isn't valid, and we can't compensate for it right now."); } else { success = true; } } Current.DB.Users.InsertOnSubmit(u); var o = new UserOpenId(); o.OpenIdClaim = openIdClaim; o.User = u; Current.DB.UserOpenIds.InsertOnSubmit(o); Current.DB.SubmitChanges(); return u; }
public int? GuessUserId(User user) { if (user.IsAnonymous || !AppSettings.GuessUserId) return null; string cacheKey = "UserIdForSite" + Id + "_" + user.Id; var currentId = HttpContext.Current.Session[cacheKey] as int?; if (currentId == null) { int? id = FindUserId(user); if (id != null) { HttpContext.Current.Cache[cacheKey] = id; } } currentId = HttpContext.Current.Cache[cacheKey] as int?; if (currentId == null) { HttpContext.Current.Cache[cacheKey] = -1; } return currentId != -1 ? currentId : null; }
public static AsyncResult Execute(ParsedQuery query, User user, Site site, QueryContextData context) { string userTag = user.IsAnonymous ? user.IPAddress : user.Id.ToString(); List<Task> activeTasks; running.TryGetValue(userTag, out activeTasks); if (activeTasks != null) { lock(activeTasks) { if (activeTasks.Where(t => !t.IsCompleted).Count() >= AppSettings.ConcurrentQueries) { throw new ApplicationException("Too many queries are running, you may only run " + AppSettings.ConcurrentQueries + " queries at a time"); } } } else { running.TryAdd(userTag, new List<Task>()); activeTasks = running[userTag]; } AsyncResult result = new AsyncResult { JobId = Guid.NewGuid(), State = AsyncState.Pending, ParsedQuery = query, Site = site, LastPoll = DateTime.UtcNow, QueryContextData = context }; Task task = new Task(() => { try { result.QueryResults = QueryRunner.GetResults(query, site, user, result); if (result.State == AsyncState.Pending) { result.State = AsyncState.Success; } } catch (Exception e) { result.Exception = e; result.State = AsyncState.Failure; } }); task.ContinueWith(ignore => { result.CompletionDate = DateTime.UtcNow; lock (activeTasks) { activeTasks.RemoveAll(t => t.IsCompleted); } }); result.Task = task; jobs.TryAdd(result.JobId, result); task.Start(); lock(activeTasks) { activeTasks.Add(task); } // give it some time to get results ... System.Threading.Thread.Sleep(50); return result; }
public static void LogRevisionExecution(User user, int siteId, int revisionId) { int updated = Current.DB.Query<int>(@" UPDATE RevisionExecutions SET ExecutionCount = ExecutionCount + 1, LastRun = @last WHERE RevisionId = @revision AND SiteId = @site AND UserId " + (user.IsAnonymous ? "IS NULL" : "= @user") + @" SELECT @@ROWCOUNT", new { revision = revisionId, site = siteId, user = user.Id, last = DateTime.UtcNow } ).FirstOrDefault(); if (updated == 0) { Current.DB.Execute(@" INSERT INTO RevisionExecutions( ExecutionCount, FirstRun, LastRun, RevisionId, SiteId, UserId ) VALUES( 1, @first, @last, @revision, @site, @user )", new { first = DateTime.UtcNow, last = DateTime.UtcNow, revision = revisionId, site = siteId, user = (user.IsAnonymous ? (int?)null : user.Id) } ); } }
private void IssueFormsTicket(User user) { var ticket = new FormsAuthenticationTicket( 1, user.Id.ToString(), DateTime.Now, DateTime.Now.AddYears(2), true, ""); string encryptedTicket = FormsAuthentication.Encrypt(ticket); var authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Expires = ticket.Expiration, HttpOnly = true, Secure = Current.IsSecureConnection }; Response.Cookies.Add(authenticationCookie); }
public static QueryResults GetResults(ParsedQuery query, Site site, User user, AsyncQueryRunner.AsyncResult result = null) { if (query.TargetSites != TargetSites.Current) { return GetMultiSiteResults(query, user, result); } else { return GetSingleSiteResults(query, site, user, result); } }
public static QueryResults GetMultiSiteResults(ParsedQuery parsedQuery, User currentUser) { var sites = Current.DB.Sites.ToList(); if (parsedQuery.ExcludesMetas) { sites = sites.Where(s => !s.Url.Contains("meta.")).ToList(); } var firstSite = sites.First(); var results = QueryRunner.GetSingleSiteResults(parsedQuery, firstSite, currentUser); StringBuilder buffer = new StringBuilder(); if (results.ResultSets.First().Columns.Where(c => c.Name == "Pivot").Any()) { foreach (var info in results.ResultSets.First().Columns) { if (info.Name == "Pivot") { info.Name = firstSite.Name + " Pivot"; break; } } foreach (var s in sites.Skip(1)) { try { var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser); results.ExecutionTime += tmp.ExecutionTime; MergePivot(s, results, tmp); } catch (Exception e) { // don't blow up here ... just skip the site. } } } else { results = results.ToTextResults(); AddBody(buffer, results, firstSite); foreach (var s in sites.Skip(1)) { try { var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser).ToTextResults(); results.ExecutionTime += tmp.ExecutionTime; AddBody(buffer, tmp, s); } catch (Exception e) { // don't blow up ... just skip the site } } } results.Messages = buffer.ToString(); results.MultiSite = true; results.ExcludeMetas = parsedQuery.ExcludesMetas; return results; }
private static QueryResults GetMultiSiteResults(ParsedQuery parsedQuery, User currentUser, AsyncQueryRunner.AsyncResult result = null) { var sites = Current.DB.Sites.All(); if (parsedQuery.TargetSites == TargetSites.AllNonMetaSites) { sites = sites.Where(s => !s.Url.Contains("meta.")).ToList(); } else if (parsedQuery.TargetSites == TargetSites.AllMetaSites) { sites = sites.Where(s => s.Url.Contains("meta.")).ToList(); } else if (parsedQuery.TargetSites == TargetSites.AllNonMetaSitesButSO) { sites = sites.Where(s => !s.Url.Contains("meta.") && !s.Url.Contains("stackoverflow.")).ToList(); } else if (parsedQuery.TargetSites == TargetSites.AllMetaSitesButMSO) { sites = sites.Where(s => s.Url.Contains("meta.") && !s.Url.Contains("stackoverflow.")).ToList(); } var firstSite = sites.First(); var results = QueryRunner.GetSingleSiteResults(parsedQuery, firstSite, currentUser, result); if (results.ResultSets.First().Columns.Where(c => c.Name == "Pivot").Any()) { foreach (var info in results.ResultSets.First().Columns) { if (info.Name == "Pivot") { info.Name = firstSite.Name + " Pivot"; break; } } foreach (var s in sites.Skip(1)) { try { var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser); results.ExecutionTime += tmp.ExecutionTime; MergePivot(s, results, tmp); } catch (Exception) { // don't blow up here ... just skip the site. } } } else { results.ResultSets[0].Columns.Add(new ResultColumnInfo { Name = "Site Name", Type = ResultColumnType.Site }); foreach (var row in results.ResultSets[0].Rows) { row.Add(sites.First().SiteInfo); } foreach (var s in sites.Skip(1)) { if (result != null && result.Cancelled) { break; } try { var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser, result); foreach (var row in tmp.ResultSets[0].Rows) { row.Add(s.SiteInfo); results.ResultSets[0].Rows.Add(row); } results.ExecutionTime += tmp.ExecutionTime; results.Messages += "\n" + tmp.Messages; } catch (Exception) { // don't blow up ... just skip the site } } } results.TargetSites = parsedQuery.TargetSites; return results; }
public static QueryResults GetSingleSiteResults(ParsedQuery query, Site site, User user) { QueryResults results = null; var timer = new Stopwatch(); timer.Start(); var cache = QueryUtil.GetCachedResults(query, site.Id); if (cache != null) { if (!query.IncludeExecutionPlan || cache.ExecutionPlan != null) { results = new QueryResults(); results.WithCache(cache); results.Truncated = cache.Truncated; results.Messages = cache.Messages; results.FromCache = true; // If we didn't ask for the execution plan, don't return it if (!query.IncludeExecutionPlan) { results.ExecutionPlan = null; } } } timer.Stop(); if (results == null) { results = ExecuteNonCached(query, site, user); results.FromCache = false; AddResultToCache(results, query, site, cache != null); } else { results.ExecutionTime = timer.ElapsedMilliseconds; } results.Url = site.Url; results.SiteId = site.Id; results.SiteName = site.Name.ToLower(); return results; }