context: using System;
  using System.Collections.Generic;
  using System.Configuration;
  using System.Data.Linq;
  using System.IO;
  using System.Linq;
  using System.Net;
  using System.Net.Mail;
  using System.Text;
  using System.Web;
  using System.Web.Security;
  using System.Web.SessionState;
  using CmsData;
  using CmsData.API;
  using CmsWeb.Areas.Manage.Models;
  using UtilityExtensions;
  
  namespace CmsWeb.Models
  {
  	public class AccountModel
  	{
  		public string GetNewFileName(string path)
  		{
  			while (File.Exists(path))
  			{
  				var ext = Path.GetExtension(path);
  				var fn = Path.GetFileNameWithoutExtension(path) + "a" + ext;
  				var dir = Path.GetDirectoryName(path);
  				path = Path.Combine(dir, fn);
  			}
  			return path;
  		}
  
  		public string CleanFileName(string fn)
  		{
  			fn = fn.Replace(' ', '_');
  			fn = fn.Replace('(', '-');
  			fn = fn.Replace(')', '-');
  			fn = fn.Replace(',', '_');
  			fn = fn.Replace("#", "");
  			fn = fn.Replace("!", "");
  			fn = fn.Replace("$", "");
  			fn = fn.Replace("%", "");
  			fn = fn.Replace("&", "_");
  			fn = fn.Replace("'", "");
  			fn = fn.Replace("+", "-");
  			fn = fn.Replace("=", "-");
  			return fn;
  		}
  
  		public static string GetValidToken(string otltoken)
  		{
  			if (!otltoken.HasValue())
  				return null;
  			var guid = otltoken.ToGuid();
  			if (guid == null)
  				return null;
  			var ot = DbUtil.Db.OneTimeLinks.SingleOrDefault(oo => oo.Id == guid.Value);
  			if (ot == null)
  				return null;
  			if (ot.Used)
  				return null;
  			if (ot.Expires.HasValue && ot.Expires < DateTime.Now)
  				return null;
  			ot.Used = true;
  			DbUtil.Db.SubmitChanges();
  			return ot.Querystring;
  		}
  
  		private const string STR_UserName2 = "UserName2";
  		public static string UserName2
  		{
  			get { return HttpContext.Current.Items[STR_UserName2] as String; }
  			set { HttpContext.Current.Items[STR_UserName2] = value; }
  		}
  
  		public static UserValidationResult AuthenticateMobile(string role = null, bool checkOrgMembersOnly = false, bool requirePin = false)
  		{
  			var userStatus = GetUserViaCredentials() ?? GetUserViaSessionToken(requirePin);
  
  			if (userStatus == null)
  				return UserValidationResult.Invalid(UserValidationStatus.ImproperHeaderStructure, "Could not authenticate user, Authorization or SessionToken headers likely missing.", null);
  				//throw new Exception("Could not authenticate user, Authorization or SessionToken headers likely missing.");
  
  			if (!userStatus.IsValid)
  				return userStatus;
  
  			var user = userStatus.User;
  
  			var roleProvider = CMSRoleProvider.provider;
  			if (role == null)
  				role = "Access";
  
  			if (roleProvider.RoleExists(role))
  			{
  				if (!roleProvider.IsUserInRole(user.Username, role))
  				{
  					userStatus.Status = UserValidationStatus.UserNotInRole;
  					return userStatus;
  				}
  			}
  
  			UserName2 = user.Username;
  			SetUserInfo(user.Username, HttpContext.Current.Session, deleteSpecialTags: false);
  			//DbUtil.LogActivity("iphone auth " + user.Username);
  
  			if (checkOrgMembersOnly && !Util2.OrgLeadersOnlyChecked)
  			{
  				DbUtil.LogActivity("iphone leadersonly check " + user.Username);
  				if (!Util2.OrgLeadersOnly && roleProvider.IsUserInRole(user.Username, "OrgLeadersOnly"))
  				{
  					Util2.OrgLeadersOnly = true;
  					DbUtil.Db.SetOrgLeadersOnly();
  					DbUtil.LogActivity("SetOrgLeadersOnly");
  				}
  				Util2.OrgLeadersOnlyChecked = true;
  			}
  
  			ApiSessionModel.SaveApiSession(userStatus.User, requirePin, HttpContext.Current.Request.Headers["PIN"].ToInt2());
  
  			return userStatus;
  		}
  		public static UserValidationResult AuthenticateMobile2(bool checkOrgMembersOnly = false, bool requirePin = false)
  		{
  			var userStatus = GetUserViaCredentials() ?? GetUserViaSessionToken(requirePin);
  
  		    if (userStatus == null)
  		    {
  				//DbUtil.LogActivity("userStatus==null");
  				return UserValidationResult.Invalid(UserValidationStatus.ImproperHeaderStructure, "Could not authenticate user, Authorization or SessionToken headers likely missing.", null);
  				//throw new Exception("Could not authenticate user, Authorization or SessionToken headers likely missing.");
  		    }
  
  			if (!userStatus.IsValid)
  				return userStatus;
  
  			var user = userStatus.User;
  
  			var roleProvider = CMSRoleProvider.provider;
  
  			UserName2 = user.Username;
  			SetUserInfo(user.Username, HttpContext.Current.Session, deleteSpecialTags: false);
  
  			if (checkOrgMembersOnly && !Util2.OrgLeadersOnlyChecked)
  			{
  				DbUtil.LogActivity("iphone leadersonly check " + user.Username);
  				if (!Util2.OrgLeadersOnly && roleProvider.IsUserInRole(user.Username, "OrgLeadersOnly"))
  				{
  					Util2.OrgLeadersOnly = true;
  					DbUtil.Db.SetOrgLeadersOnly();
  					DbUtil.LogActivity("SetOrgLeadersOnly");
  				}
  				Util2.OrgLeadersOnlyChecked = true;
  			}
  
  			ApiSessionModel.SaveApiSession(userStatus.User, requirePin, HttpContext.Current.Request.Headers["PIN"].ToInt2());
  
  			return userStatus;
  		}
  
  
  		public static UserValidationResult ResetSessionExpiration(string sessionToken)
  		{
  			if (string.IsNullOrEmpty(sessionToken))
  				return UserValidationResult.Invalid(UserValidationStatus.ImproperHeaderStructure, "Could not authenticate user, Authorization or SessionToken headers likely missing.", null);
  				//throw new ArgumentNullException("sessionToken");
  
  			var userStatus = AuthenticateMobile(requirePin: true);
  
  			if (userStatus.Status == UserValidationStatus.Success
  				 || userStatus.Status == UserValidationStatus.PinExpired
  				 || userStatus.Status == UserValidationStatus.SessionTokenExpired)
  			{
  				var result = ApiSessionModel.ResetSessionExpiration(userStatus.User, HttpContext.Current.Request.Headers["PIN"].ToInt2());
  			    if (!result)
  			        return UserValidationResult.Invalid(UserValidationStatus.PinInvalid);
  
  				userStatus.Status = UserValidationStatus.Success;
  			}
  
  			return userStatus;
  		}
  
  	    public static void ExpireSessionToken(string sessionToken)
  	    {
  	        ApiSessionModel.ExpireSession(Guid.Parse(sessionToken));
  	    }
  
  		private static UserValidationResult GetUserViaSessionToken(bool requirePin)
  		{
  			var sessionToken = HttpContext.Current.Request.Headers["SessionToken"];
  		    if (string.IsNullOrEmpty(sessionToken))
  		    {
      			//DbUtil.LogActivity("GetUserViaSession==null");
  				return null;
  		    }
  
  			var result = ApiSessionModel.DetermineApiSessionStatus(Guid.Parse(sessionToken), requirePin, HttpContext.Current.Request.Headers["PIN"].ToInt2());
  
  			//DbUtil.LogActivity("GetUserViaSession==" + result.Status.ToString());
  
  			switch (result.Status)
  			{
  				case ApiSessionStatus.SessionTokenNotFound:
  					return UserValidationResult.Invalid(UserValidationStatus.SessionTokenNotFound);
  				case ApiSessionStatus.SessionTokenExpired:
  					return UserValidationResult.Invalid(UserValidationStatus.SessionTokenExpired, user: result.User);
  				case ApiSessionStatus.PinExpired:
  					return UserValidationResult.Invalid(UserValidationStatus.PinExpired, user: result.User);
  				case ApiSessionStatus.PinInvalid:
  					return UserValidationResult.Invalid(UserValidationStatus.PinInvalid);
  			}
  
  			return ValidateUserBeforeLogin(result.User.Username, HttpContext.Current.Request.Url.OriginalString, result.User, userExists: true);
  		}
  
  		private static UserValidationResult GetUserViaCredentials()
  		{
  			string username;
  			string password;
  
  			var auth = HttpContext.Current.Request.Headers["Authorization"];
  			if (auth.HasValue())
  			{
  				var cred = Encoding.ASCII.GetString(
  					 Convert.FromBase64String(auth.Substring(6))).SplitStr(":", 2);
  				username = cred[0];
  				password = cred[1];
  			}
  			else
  			{
  				// NOTE: this is necessary only for the old iOS application
  				username = HttpContext.Current.Request.Headers["username"];
  				password = HttpContext.Current.Request.Headers["password"];
  			}
  
  			if (!string.IsNullOrEmpty(username) || !string.IsNullOrEmpty(password))
  			{
  				var creds = new NetworkCredential(username, password);
  				UserName2 = creds.UserName;
  				//DbUtil.LogActivity("GetUserViaCreds");
  				return AuthenticateLogon(creds.UserName, creds.Password, HttpContext.Current.Request.Url.OriginalString);
  			}
  
  			//DbUtil.LogActivity("GetUserViaCreds==null");
  			return null;
  		}
  
  		public static UserValidationResult AuthenticateLogon(string userName, string password, string url)
  		{
  			var userQuery = DbUtil.Db.Users.Where(uu =>
  
gt: 				 uu.Username == userName ||