protected void Page_Load(object sender, EventArgs e) { if (!CurrentOrganization.IsEconomyEnabled) { Response.Redirect("/Pages/v5/Financial/EconomyNotEnabled.aspx", true); return; } PageIcon = "iconshock-stamped-paper"; PageAccessRequired = new Access(CurrentOrganization, AccessAspect.Participant, AccessType.Read); // No specific access aspect for owning a budget (yet?) if (!Page.IsPostBack) { Localize(); } // this.TextDenyReason.Style [HtmlTextWriterStyle.FontSize] = "60% !important"; this._attestationRights = GetAttestationRights(); this._documentList = new List <RepeatedDocument>(); this.LiteralCanOverdraftBudgets.Text = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Administration)).ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); PopulateInboundInvoices(); // PopulateExpenses(); // PopulateSalaries(); RegisterControl(EasyUIControl.DataGrid); this.RepeaterLightboxItems.DataSource = this._documentList; this.RepeaterLightboxItems.DataBind(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string pattern = HttpUtility.UrlDecode(Request.QueryString["Pattern"]); string geographyString = Request.QueryString["GeographyId"]; int geographyId = int.Parse(geographyString); Geography geography = Geography.FromIdentity(geographyId); if ( !CurrentAuthority.HasAccess(new Access(CurrentOrganization, geography, AccessAspect.PersonalData, AccessType.Read))) { throw new UnauthorizedAccessException("nope"); } People matches = People.FromOrganizationAndGeographyWithPattern(CurrentOrganization, geography, pattern); matches = CurrentAuthority.FilterPeople(matches); if (matches == null) { matches = new People(); } if (matches.Count > 1000) { matches.RemoveRange(1000, matches.Count - 1000); } List <string> jsonPeople = new List <string>(); string editPersonTemplate = "\"actions\":\"<a href='javascript:masterBeginEditPerson({0})'><img src='/Images/Icons/iconshock-wrench-128x96px-centered.png' height='16' width='24' /></a>\""; foreach (Person person in matches) { string onePerson = '{' + String.Format( "\"id\":\"{0}\",\"name\":\"<span class='spanUser{0}Name'>{1}</span>\",\"avatar16Url\":\"{2}\",\"geographyName\":\"{3}\",\"mail\":\"<span class='spanUser{0}Mail'>{4}</span>\",\"phone\":\"<span class='spanUser{0}Phone'>{5}</span>\"", person.Identity, JsonSanitize(person.Canonical), person.GetSecureAvatarLink(16), JsonSanitize(person.Geography.Name), JsonSanitize(person.Mail), JsonSanitize(person.Phone)) + "," + String.Format( editPersonTemplate, person.Identity) + '}'; jsonPeople.Add(onePerson); } string result = '[' + String.Join(",", jsonPeople.ToArray()) + ']'; Response.Output.WriteLine(result); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; FinancialTransactions unbalancedTransactions = FinancialTransactions.GetUnbalanced(CurrentOrganization); List <string> rows = new List <string>(); if ( CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read))) { if (unbalancedTransactions.Count == 0) { if (rows.Count == 0) { // If there are no transactions in this time period, say so Response.Output.WriteLine("[{\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.BalanceTransactions_NoUnbalancedTransactions) + "\"}]"); Response.End(); return; } } foreach (FinancialTransaction transaction in unbalancedTransactions) { string accountName = string.Empty; FinancialTransactionRows txRows = transaction.Rows; if (txRows.Count > 1) { accountName = Resources.Global.Global_Several_Display; } else { // one transaction row (we know there's not zero rows, because the transaction is unbalanced, which requires at least one nonzero row) accountName = txRows[0].AccountName; } string row = String.Format( "\"id\":\"{0:N0}\",\"description\":\"{1}\",\"accountName\":\"{2}\",\"delta\":\"{3:+#,#.00;−#,#.00}\",\"dateTime\":\"{4:yyyy-MMM-dd HH:mm}\"", transaction.OrganizationSequenceId, JsonSanitize(transaction.Description), JsonSanitize(accountName), txRows.AmountCentsTotal / 100.0, transaction.DateTime); row += String.Format( ",\"action\":\"<img src='/Images/Icons/iconshock-wrench-128x96px-centered.png' height='16' width='24' class='LocalIconFix' txId='{0}' />\"", transaction.Identity); rows.Add("{" + row + "}"); } } Response.Output.WriteLine("[" + String.Join(",", rows) + "]"); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string pattern = HttpUtility.UrlDecode(Request.QueryString["Pattern"]); string geographyString = Request.QueryString["GeographyId"]; int geographyId = int.Parse(geographyString); Geography geography = Geography.FromIdentity(geographyId); if ( !CurrentAuthority.HasAccess(new Access(CurrentOrganization, geography, AccessAspect.PersonalData, AccessType.Read))) { throw new UnauthorizedAccessException("nope"); } People matches = People.FromOrganizationAndGeographyWithPattern(CurrentOrganization, geography, pattern); matches = CurrentAuthority.FilterPeople(matches); if (matches == null) { matches = new People(); } if (matches.Count > 1000) { matches.RemoveRange(1000, matches.Count - 1000); } List <string> jsonPeople = new List <string>(); foreach (Person person in matches) { string onePerson = '{' + String.Format( "\"id\":\"{0}\",\"name\":\"{1}\",\"avatar16Url\":\"{2}\",\"geographyName\":\"{3}\",\"mail\":\"{4}\",\"phone\":\"{5}\"", person.Identity, JsonSanitize(person.Canonical), person.GetSecureAvatarLink(16), JsonSanitize(person.Geography.Name), JsonSanitize(person.Mail), JsonSanitize(person.Phone)) + '}'; jsonPeople.Add(onePerson); } string result = '[' + String.Join(",", jsonPeople.ToArray()) + ']'; Response.Output.WriteLine(result); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Financials, AccessType.Read))) { throw new UnauthorizedAccessException(); } ExpenseClaims claims = ExpenseClaims.ForOrganization(CurrentOrganization); claims = claims.WhereUnvalidated; // Format as JSON and return Response.ContentType = "application/json"; string json = FormatAsJson(claims); Response.Output.WriteLine(json); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string pattern = Request.QueryString["namePattern"]; People matches = People.FromNamePattern(pattern); matches = CurrentAuthority.FilterPeople(matches); if (matches == null) { matches = new People(); } // TODO: Add filter so the people must have active memberships of this org or any org below it (fixes #1) if (matches.Count > 10) { matches.RemoveRange(10, matches.Count - 10); } List <string> jsonPeople = new List <string>(); foreach (Person person in matches) { string onePerson = '{' + String.Format("\"id\":\"{0}\",\"name\":\"{1}\",\"avatar16Url\":\"{2}\"", person.Identity, JsonSanitize(person.Canonical), person.GetSecureAvatarLink(16)) + '}'; jsonPeople.Add(onePerson); } string result = '[' + String.Join(",", jsonPeople.ToArray()) + ']'; Response.Output.WriteLine(result); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string yearString = Request.QueryString["Year"]; string monthString = Request.QueryString["Month"]; int year = Int32.Parse(yearString); int month = Int32.Parse(monthString); if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Read))) { throw new UnauthorizedAccessException("Access denied because security tokens say so"); } DateTime periodStart, periodEnd; bool zeroStart = false; bool zeroEnd = false; bool displayDescription = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read)); // HACK HACK HACK if (CurrentOrganization.Identity == 8 && CurrentOrganization.Name.StartsWith("Rick Falkvinge")) { // TODO displayDescription = true; // FIX THIS WITH A DAMN SETTING, YOU MORON, DON'T HARDCODE IT } bool canSeeAudit = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Auditing, AccessType.Read)); if (month > 0 && month <= 12) { periodStart = new DateTime(year, month, 1); periodEnd = periodStart.AddMonths(1); } else if (month > 20 && month < 25) // quarters 1..4 are coded as months 21..24 { periodStart = new DateTime(year, (month - 21) * 3 + 1, 1); periodEnd = periodStart.AddMonths(3); } else if (month == 31) // "whole year" is coded as month 31 { periodStart = new DateTime(year, 1, 1); periodEnd = new DateTime(year + 1, 1, 1); } else { throw new ArgumentException("Invalid month supplied: " + month.ToString(CultureInfo.InvariantCulture)); } DateTime profitLossStart = new DateTime(periodStart.Year, 1, 1); DateTime balanceStart = Constants.DateTimeLow; FinancialAccounts accounts = FinancialAccounts.ForOrganization(CurrentOrganization); FinancialAccountRows rows = accounts.GetRows(periodStart, periodEnd); StringBuilder result = new StringBuilder(16384); Dictionary <int, Int64> runningBalanceLookup = new Dictionary <int, long>(); Dictionary <int, FinancialAccount> accountLookup = new Dictionary <int, FinancialAccount>(); foreach (FinancialAccount accountLoop in accounts) { accountLookup[accountLoop.Identity] = accountLoop; } int currentTransactionId = 0; int rowCount = 0; foreach (FinancialAccountRow row in rows) { string creditString = string.Empty; string debitString = string.Empty; FinancialAccount account = accountLookup[row.FinancialAccountId]; if (!runningBalanceLookup.ContainsKey(row.FinancialAccountId)) { if (account.AccountType == FinancialAccountType.Asset || account.AccountType == FinancialAccountType.Debt) { runningBalanceLookup[account.Identity] = account.GetDeltaCents(balanceStart, periodStart); } else { runningBalanceLookup[account.Identity] = account.GetDeltaCents(profitLossStart, periodStart); } } if (row.FinancialTransactionId != currentTransactionId) { // We're starting a new transaction here // If it's not the first one, close the previous one first if (currentTransactionId != 0) { result.Append("]},"); } FinancialTransaction transaction = row.Transaction; string description = transaction.Description; string hasDoxString = "<img src='/Images/Icons/iconshock-search-256px.png' onmouseover=\"this.src='/Images/Icons/iconshock-search-hot-256px.png';\" onmouseout=\"this.src='/Images/Icons/iconshock-search-256px.png';\" data-txid='{0}' class='LocalViewDox' style='cursor:pointer' height='20' width='20' />" + "<img src='/Images/Icons/iconshock-download-240px.png' onmouseover=\"this.src='/Images/Icons/iconshock-download-hot-240px.png';\" onmouseout=\"this.src='/Images/Icons/iconshock-download-240px.png';\" data-docid='{1}' data-docname=\"{2}\" class='LocalDownloadDox' style='cursor:pointer' height='18' width='18' />"; string actionHtml = string.Empty; Documents documents = Documents.ForObject(transaction.Dependency ?? transaction); if (documents.Count > 0) { foreach (Document doc in documents) { actionHtml += String.Format("<a href='/Pages/v5/Support/StreamUpload.aspx?DocId={0}&hq=1' data-caption=\"{1}\" class='FancyBox_Gallery' data-fancybox='{2}'></a>", doc.Identity, doc.ClientFileName.Replace("\"", "'"), transaction.Identity); } actionHtml = String.Format(hasDoxString, row.FinancialTransactionId.ToString(CultureInfo.InvariantCulture), documents[0].Identity, CurrentOrganization.Name + " - " + Resources.Global.Financial_GeneralLedger + " " + transaction.DateTime.ToShortDateString() + " - " + Resources.Global.Financial_TransactionIdShort + transaction.OrganizationSequenceId.ToString("N0")) + "<span class='hiddenDocLinks'>" + actionHtml + "</span>"; } result.Append("{" + String.Format( "\"id\":\"{0:N0}\",\"idDisplay\":\"<span class='weight-more-emphasis'>{0:N0}</span>\",\"datetime\":\"<span class='weight-more-emphasis'>{1:MMM-dd HH:mm}</span>\",\"txDescription\":\"<span class='weight-more-emphasis tx-description'>{2}</span>\",\"action\":\"{3}\"," + "\"state\":\"open\",\"children\":[", row.Transaction.OrganizationSequenceId, row.TransactionDateTime, JsonSanitize(description), JsonSanitize(actionHtml))); if (transaction.Dependency != null) { IHasIdentity dependency = transaction.Dependency; string info = string.Empty; Documents docs = null; if (dependency is VatReport) { VatReport report = (VatReport)dependency; if (report.OpenTransactionId == transaction.Identity) { info = String.Format(Resources.Pages.Ledgers.InspectLedgers_TxInfo_OpenVatReport, report.DescriptionShort); } else if (report.CloseTransactionId == transaction.Identity) { info = String.Format(Resources.Pages.Ledgers.InspectLedgers_TxInfo_CloseVatReport, report.DescriptionShort); } } // TODO: Continue here with adding Info row under transactions where it's helpful // TODO: Remember that the Info row needs cell merging, colspan=5 or =6 } /* * result.Append("{" + String.Format( * "\"id\":\"{0:N0}\",\"datetime\":\"{1:MMM-dd HH:mm}\",\"description\":\"{2}\"," + * "\"action\":\"{6}\",\"state\":\"open\",\"children\":[", * row.Transaction.OrganizationSequenceId, * row.TransactionDateTime, * JsonSanitize(description), * debitString, * creditString, * runningBalanceLookup[row.FinancialAccountId]/100.0, * JsonSanitize(actionHtml))); */ currentTransactionId = row.FinancialTransactionId; rowCount = 1; } else { // still same transaction result.Append(","); rowCount++; } if (row.AmountCents < 0) { creditString = String.Format("{0:N2}", row.AmountCents / 100.0); } else if (row.AmountCents > 0) { debitString = String.Format("{0:N2}", row.AmountCents / 100.0); } runningBalanceLookup[row.FinancialAccountId] += row.AmountCents; /* * if (canSeeAudit) * { * actionHtml += * String.Format ( * " <img src=\"/Images/Icons/iconshock-flag-white-16px.png\" class=\"LocalIconFlag\" txId=\"{0}\" />", * row.FinancialTransactionId.ToString (CultureInfo.InvariantCulture)); * }*/ //result.Append("{\"description\":\"child\"}"); string accountClass; switch (accountLookup[row.FinancialAccountId].AccountType) { case FinancialAccountType.Asset: accountClass = Resources.Global.Financial_Asset; break; case FinancialAccountType.Debt: accountClass = Resources.Global.Financial_Debt; break; case FinancialAccountType.Income: accountClass = Resources.Global.Financial_Income; break; case FinancialAccountType.Cost: accountClass = Resources.Global.Financial_Cost; break; default: throw new NotImplementedException(); } string accountName = account.Name; if (account.ParentIdentity != 0) { if (!accountLookup.ContainsKey(account.ParentIdentity)) { accountLookup[account.ParentIdentity] = account.Parent; } accountName = accountLookup[account.ParentIdentity].Name + " » " + accountName; } result.Append("{" + String.Format( "\"id\":\"{0:N0}-{6:N0}\",\"idDisplay\":\"{0:N0}:{6:N0}\",\"datetime\":\"{1}\",\"txDescription\":\"{2}\"," + "\"deltaPos\":\"{3}\",\"deltaNeg\":\"{4}\",\"balance\":\"{5:N2}\"", row.Transaction.OrganizationSequenceId, JsonSanitize(accountClass), JsonSanitize(accountName), debitString, creditString, runningBalanceLookup[row.FinancialAccountId] / 100.0, rowCount) + "}"); } if (rows.Count == 0) { // If there are no transactions in this time period, say so result.Append("{\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_NoTransactions) + "\"},"); } Response.Output.WriteLine("[" + result.ToString().TrimEnd(',') + "]}]"); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string accountIdString = Request.QueryString["AccountId"]; string yearString = Request.QueryString["Year"]; string monthString = Request.QueryString["Month"]; string emptyResponse = "[{\"id\":\"-\",\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_PleaseSelectAccount) + "\"}]"; if (string.IsNullOrEmpty(accountIdString) || string.IsNullOrEmpty(yearString) || string.IsNullOrEmpty(monthString) || accountIdString == "undefined") { Response.Output.WriteLine(emptyResponse); Response.End(); } int accountId = Int32.Parse(accountIdString); int year = Int32.Parse(yearString); int month = Int32.Parse(monthString); DateTime dawnOfMankind = new DateTime(1901, 1, 1); // no org will ever import bookkeeping from before this date if (accountId <= 0) { Response.Output.WriteLine(emptyResponse); Response.End(); } FinancialAccount account = FinancialAccount.FromIdentity(accountId); if (account.OrganizationId != CurrentOrganization.Identity) { throw new UnauthorizedAccessException("All the nopes in the world"); } if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Read))) { throw new UnauthorizedAccessException("Access denied because security tokens say so"); } DateTime periodStart, periodEnd; DateTime balanceStart = dawnOfMankind; bool zeroStart = false; bool zeroEnd = false; bool displayDescription = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read)); bool canSeeAudit = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Auditing, AccessType.Read)); if (month > 0 && month <= 12) { periodStart = new DateTime(year, month, 1); periodEnd = periodStart.AddMonths(1); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { balanceStart = new DateTime(year, 1, 1); if (month == 1) { zeroStart = true; } if (month == 12) { zeroEnd = true; } } } else if (month > 20 && month < 25) // quarters 1..4 are coded as months 21..24 { periodStart = new DateTime(year, (month - 21) * 3 + 1, 1); periodEnd = periodStart.AddMonths(3); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { balanceStart = new DateTime(year, 1, 1); if (month == 21) { zeroStart = true; } if (month == 24) { zeroEnd = true; } } } else if (month == 31) // "whole year" is coded as month 31 { periodStart = new DateTime(year, 1, 1); periodEnd = new DateTime(year + 1, 1, 1); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { zeroStart = true; zeroEnd = true; } } else { throw new ArgumentException("Invalid month supplied: " + month.ToString(CultureInfo.InvariantCulture)); } FinancialAccountRows rows = account.GetRows(periodStart, periodEnd); StringBuilder result = new StringBuilder(16384); Int64 runningBalance = 0L; string startString = Resources.Pages.Ledgers.InspectLedgers_InboundBalanceZero; string endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalanceZero; if (!zeroStart) { runningBalance = account.GetDeltaCents(balanceStart, periodStart); startString = Resources.Pages.Ledgers.InspectLedgers_InboundBalance; } if (!zeroEnd) { endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalance; } else if (periodEnd > DateTime.Now) { // account is zeroed at end of this period, but we're not yet at end of period, so add a "to date" disclaimer endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalanceZeroToDate; } result.Append("{" + String.Format("\"description\":\"{0}\",\"balance\":\"{1:N0}\"", JsonSanitize(startString), runningBalance / 100.0) + "},"); foreach (FinancialAccountRow row in rows) { string creditString = string.Empty; string debitString = string.Empty; string description = row.Description; if (!displayDescription) { description = Resources.Pages.Ledgers.InspectLedgers_TxDetail_DescriptionWithheld; } if (row.AmountCents < 0) { creditString = String.Format("{0:N0}", row.AmountCents / 100.0); } else if (row.AmountCents > 0) { debitString = String.Format("{0:N0}", row.AmountCents / 100.0); } runningBalance += row.AmountCents; string actionHtml = String.Format( "<img src=\"/Images/Icons/iconshock-magnifyingglass-16px.png\" class=\"LocalIconInspect\" txId=\"{0}\" />", row.FinancialTransactionId.ToString(CultureInfo.InvariantCulture)); if (canSeeAudit) { actionHtml += String.Format( " <img src=\"/Images/Icons/iconshock-flag-white-16px.png\" class=\"LocalIconFlag\" txId=\"{0}\" />", row.FinancialTransactionId.ToString(CultureInfo.InvariantCulture)); } result.Append("{" + String.Format( "\"id\":\"{0:N0}\",\"datetime\":\"{1:MMM-dd HH:mm}\",\"description\":\"{2}\"," + "\"deltaPos\":\"{3}\",\"deltaNeg\":\"{4}\",\"balance\":\"{5:N0}\",\"action\":\"{6}\"", row.FinancialTransactionId, row.TransactionDateTime, JsonSanitize(description), debitString, creditString, runningBalance / 100.0, JsonSanitize(actionHtml)) + "},"); } if (rows.Count == 0) { // If there are no transactions in this time period, say so result.Append("{\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_NoTransactions) + "\"},"); } result.Append("{" + String.Format("\"description\":\"{0}\",\"balance\":\"{1:N0}\"", JsonSanitize(endString), runningBalance / 100.0) + "},"); Response.Output.WriteLine("[" + result.ToString().TrimEnd(',') + "]"); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; // If level if system-wide, execute this block. Also, move the data to the real place, please JsonPositions rootPositions = new JsonPositions(); _customCookieClass = "LocalPosition" + Request["Cookie"]; // may be null and that's ok PositionLevel level = (PositionLevel)Enum.Parse(typeof(PositionLevel), Request["Level"]); // may throw on invalid param but so what, that's what should happen anyway if (level == PositionLevel.SystemWide) { Tree <Position> systemPositions = Positions.ForSystem().Tree; if (CurrentAuthority.HasSystemAccess()) { _assignable = true; } Response.Output.WriteLine(RecursePositionTree(systemPositions.RootNodes)); Response.End(); return; } else if (level == PositionLevel.OrganizationStrategic) { // If this level does not exist yet for this org, create a starting point Positions orgStrategicPositions = Positions.ForOrganization(CurrentOrganization).AtLevel(PositionLevel.OrganizationStrategic); if (orgStrategicPositions.Count == 0) { throw new InvalidOperationException("Positions are not initialized or are missing."); } if (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Administration))) { _assignable = true; } Response.Output.WriteLine(RecursePositionTree(orgStrategicPositions.Tree.RootNodes)); } else if (level == PositionLevel.OrganizationExecutive) { Positions orgExecutivePositions = Positions.ForOrganization(CurrentOrganization).AtLevel(PositionLevel.OrganizationExecutive); if (orgExecutivePositions.Count == 0) { throw new InvalidOperationException("Positions are not initialized or are missing."); } if (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Administration)) || CurrentAuthority.HasAccess(new Access(CurrentOrganization, Geography.Root, AccessAspect.Administration))) { _assignable = true; } Response.Output.WriteLine(RecursePositionTree(orgExecutivePositions.Tree.RootNodes)); } else if (level == PositionLevel.GeographyDefault) { Positions positions = Positions.ForOrganization(CurrentOrganization).AtLevel(PositionLevel.GeographyDefault); if (positions.Count == 0) { throw new InvalidOperationException("Positions are not initialized or are missing."); } _displayAssignments = false; // Suppresses assignment lookup, which would fail for default positions Response.Output.WriteLine(RecursePositionTree(positions.Tree.RootNodes)); // TODO: turn off assignability! } else if (level == PositionLevel.Geography) { _geographyId = Convert.ToInt32(Request["GeographyId"]); Geography geography = Geography.FromIdentity(_geographyId); if (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Administration))) { _assignable = true; } Tree <Position> positions = Positions.ForOrganizationGeography(CurrentOrganization, geography); Response.Output.WriteLine(RecursePositionTree(positions.RootNodes)); } }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string transactionIdString = Request.QueryString["TxId"]; string emptyResponse = "[{\"id\":\"-\",\"accountName\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_EmptyTransaction) + "\"}]"; if (string.IsNullOrEmpty(transactionIdString) || transactionIdString == "undefined") { Response.Output.WriteLine(emptyResponse); Response.End(); } int transactionId = Int32.Parse(transactionIdString); DateTime dawnOfMankind = new DateTime(1901, 1, 1); // no org will ever import bookkeeping from before this date if (transactionId <= 0) { Response.Output.WriteLine(emptyResponse); Response.End(); } FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId); if (transaction.OrganizationId != CurrentOrganization.Identity) { throw new UnauthorizedAccessException("All the nopes in the world"); } if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Read))) { throw new UnauthorizedAccessException("Access denied because security tokens say so"); } FinancialTransactionRows rows = transaction.Rows; StringBuilder result = new StringBuilder(16384); foreach (FinancialTransactionRow row in rows) { string creditString = string.Empty; string debitString = string.Empty; if (row.AmountCents < 0) { creditString = String.Format("{0:N2}", row.AmountCents / 100.0); } else if (row.AmountCents > 0) { debitString = String.Format("{0:N2}", row.AmountCents / 100.0); } result.Append("{" + String.Format( "\"id\":\"{0}\",\"dateTime\":\"{1:yyyy-MMM-dd HH:mm}\",\"accountName\":\"{2}\"," + "\"deltaPos\":\"{3}\",\"deltaNeg\":\"{4}\",\"initials\":\"{5}\"", row.FinancialTransactionId, row.CreatedDateTime, JsonSanitize(row.AccountName), debitString, creditString, row.CreatedByPerson != null? row.CreatedByPerson.Initials: Resources.Global.Global_System) + "},"); } Int64 amountCentsTotal = transaction.Rows.AmountCentsTotal; if (amountCentsTotal != 0) { // If the transaction is unbalanced, make a huge deal about it result.Append("{\"accountName\":\"<img src='/Images/Icons/iconshock-warning-24px.png' height='16px' width='16px' class='elementFloatFar' />" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_UnbalancedTransaction) + "\","); if (amountCentsTotal < 0) { result.AppendFormat("\"deltaPos\":\"<span class='spanAnnoyingBlink'>{0:N2}</span>\"", -amountCentsTotal / 100.0); } else if (amountCentsTotal > 0) { result.AppendFormat("\"deltaNeg\":\"<span class='spanAnnoyingBlink'>{0:N2}</span>\"", -amountCentsTotal / 100.0); } result.Append("},"); // the comma isn't really necessary here but will be stripped later and is kept for cut&paste consistency of this code block } Response.Output.WriteLine("[" + result.ToString().TrimEnd(',') + "]"); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string pattern = HttpUtility.UrlDecode(Request.QueryString["Pattern"]); string geographyString = Request.QueryString["GeographyId"]; int geographyId = int.Parse(geographyString); Geography geography = Geography.FromIdentity(geographyId); if ( !CurrentAuthority.HasAccess(new Access(CurrentOrganization, geography, AccessAspect.PersonalData, AccessType.Read))) { throw new UnauthorizedAccessException("nope"); } People matches = People.FromOrganizationAndGeographyWithPattern(CurrentOrganization, geography, pattern); matches = CurrentAuthority.FilterPeople(matches); if (matches == null) { matches = new People(); } if (matches.Count > 1000) { matches.RemoveRange(1000, matches.Count - 1000); } List <string> jsonPeople = new List <string>(); string editPersonTemplate = "\"actions\":\"<a href='javascript:masterBeginEditPerson({0})'><img src='/Images/Icons/iconshock-wrench-128x96px-centered.png' height='16' width='24' /></a>\""; Dictionary <int, Applicant> applicantLookup = new Dictionary <int, Applicant>(); if (CurrentOrganization.Parameters.ParticipationEntry == "ApplicationApproval") { // There are applications possible for this org; find them and put the Score in the Notes field Applicants applicants = Applicants.FromPeopleInOrganization(matches, CurrentOrganization); foreach (Applicant applicant in applicants) { applicantLookup[applicant.PersonId] = applicant; } } foreach (Person person in matches) { string notes = Participant.Localized(CurrentOrganization.RegularLabel, person.Gender); if (applicantLookup.ContainsKey(person.Identity)) { // If this is an applicant, use the "Notes" field for score notes = "<span class='alignRight'>" + applicantLookup[person.Identity].ScoreTotal.ToString("N0") + "</span>"; } string onePerson = '{' + String.Format( "\"id\":\"{0}\",\"name\":\"<span class='spanUser{0}Name'>{1}</span>\",\"avatar16Url\":\"{2}\",\"geographyName\":\"{3}\",\"mail\":\"<span class='spanUser{0}Mail'>{4}</span>\",\"notes\":\"{6}\",\"phone\":\"<span class='spanUser{0}Phone'>{5}</span>\"", person.Identity, JsonSanitize(person.Canonical), person.GetSecureAvatarLink(16), JsonSanitize(person.Geography.Localized), JsonSanitize(person.Mail), JsonSanitize(person.Phone), JsonSanitize(notes)) + "," + String.Format( editPersonTemplate, person.Identity) + '}'; jsonPeople.Add(onePerson); } string result = '[' + String.Join(",", jsonPeople.ToArray()) + ']'; Response.Output.WriteLine(result); Response.End(); }
protected void Page_Load(object sender, EventArgs e) { string documentIdString = Request.QueryString["DocId"]; int documentId = Int32.Parse(documentIdString); string documentDownloadName = Request.QueryString["DocName"]; documentDownloadName = documentDownloadName.Replace("\"", "'"); Document document = Document.FromIdentity(documentId); //Orgid is needed to safely verify permission int orgId = 0; // initialize to invalid bool hasPermission = false; string serverFileName = document.ServerFileName; if (document.UploadedByPersonId == this.CurrentAuthority.Person.Identity) { hasPermission = true; // can always view documents you yourself uploaded } if (CurrentOrganization.HasOpenLedgers) { hasPermission = true; } if (!hasPermission) { switch (document.DocumentType) { case DocumentType.FinancialTransaction: { /* * //TODO: Get the orgId from foreign object * if (this.CurrentAuthority.HasPermission(Permission.CanSeeEconomyDetails, orgId, -1, Authorization.Flag.ExactOrganization)) * { * hasPermission = true; * }*/ } break; case DocumentType.ExpenseClaim: case DocumentType.InboundInvoice: case DocumentType.OutboundInvoice: { int budgetId = 0; if (document.DocumentType == DocumentType.ExpenseClaim) { ExpenseClaim claim = (ExpenseClaim)document.ForeignObject; orgId = claim.Budget.OrganizationId; budgetId = claim.BudgetId; } else if (document.DocumentType == DocumentType.InboundInvoice) { InboundInvoice invoice = (InboundInvoice)document.ForeignObject; orgId = invoice.Budget.OrganizationId; budgetId = invoice.BudgetId; } else { OutboundInvoice invoice = (OutboundInvoice)document.ForeignObject; orgId = invoice.OrganizationId; budgetId = invoice.BudgetId; } FinancialAccount budget = FinancialAccount.FromIdentity(budgetId); if (budget.OwnerPersonId == CurrentUser.Identity || budget.OwnerPersonId == 0) { hasPermission = true; break; } // TODO: Security leak - check CurrentOrganization against Document's org if ( CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Financials, AccessType.Write))) { hasPermission = true; } /* * if (this.CurrentAuthority.HasPermission(Permission.CanSeeEconomyDetails, orgId, -1, Authorization.Flag.ExactOrganization)) * { * hasPermission = true; * break; * }*/ break; } case DocumentType.PaperLetter: { PaperLetter letter = (PaperLetter)document.ForeignObject; if (letter.Recipient.Identity == CurrentUser.Identity) { hasPermission = true; // A letter to the viewer } /* * // Otherwise, are there overriding permissions, if not addressed to him/her? * * else if (!letter.Personal) * { * // Unpersonal paper letter, like a rally permit. Note that bank statements should * // be considered personal as they contain donors' information in the transaction info. * * if (this.CurrentAuthority.HasPermission(Permission.CanSeeInsensitivePaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * } * else if (letter.ToPersonId == 0) * { * // Addressed to the organization, not to a specific person, but still personal. * // Typical examples include political inquiries from private citizens written on * // paper. * * if (this.CurrentAuthority.HasPermission(Permission.CanSeeSensitivePaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * } * else * { * // Addressed to a specific individual that is not the viewer, and it's personal. * // INVOCATION OF THIS CODE IS A BREACH OF THE POSTAL SECRET and should ONLY EVER * // be done for technical, not operational, reasons and preferably NEVER. * * if (this.CurrentAuthority.HasPermission(Permission.CanBreachPostalSecretPaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * }*/ } break; case DocumentType.PersonPhoto: case DocumentType.Logo: case DocumentType.Artwork: { // These are public hasPermission = true; } break; } } if (!hasPermission) { throw new Exception("Access is not allowed"); } string contentType = string.Empty; string clientFileNameLower = document.ClientFileName.ToLowerInvariant().Trim(); string serverFileNameLower = document.ServerFileName.ToLowerInvariant().Trim(); // The "Filename.Contains" here instead of "Filename.EndsWith" is because page counts are added to file names if (serverFileNameLower.EndsWith(".png") && clientFileNameLower.Contains(".pdf")) { // Converted PDF, so cut filename to raw GUID length serverFileName = serverFileName.Substring(0, serverFileName.Length - "-0001.png".Length); documentDownloadName += ".pdf"; contentType = MediaTypeNames.Application.Pdf; } else if (clientFileNameLower.EndsWith(".png")) { contentType = "image/png"; // why isn't this in MediaTypeNames? documentDownloadName += ".png"; } else if (clientFileNameLower.EndsWith(".jpg") || clientFileNameLower.EndsWith(".jpeg")) { contentType = MediaTypeNames.Image.Jpeg; documentDownloadName += ".jpg"; } else { int lastDot = clientFileNameLower.LastIndexOf('.'); if (lastDot > 0) { documentDownloadName += clientFileNameLower.Substring(lastDot); // Adds original client extension } } if (documentDownloadName.EndsWith(" 2_1") || documentDownloadName.EndsWith(" 2/1")) { // Mystery bug documentDownloadName = documentDownloadName.Substring(0, documentDownloadName.Length - 4); } string legacyMarker = string.Empty; if (!File.Exists(Document.StorageRoot + serverFileName)) { legacyMarker = "legacy/"; // for some legacy installations, all older files are placed here } // TODO: If still doesn't exist, perhaps return a friendly error image instead? if (!File.Exists(Document.StorageRoot + legacyMarker + serverFileName)) { if (!Debugger.IsAttached) // if running live; ignore FNF errors when debugging { throw new FileNotFoundException(Document.StorageRoot + legacyMarker + serverFileName); } else { Response.StatusCode = 404; Response.End(); return; } } Response.ContentType = contentType; Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + documentDownloadName + "\""); Response.TransmitFile(Document.StorageRoot + legacyMarker + serverFileName); }
protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; string yearString = Request.QueryString["Year"]; string monthString = Request.QueryString["Month"]; string emptyResponse = "[{\"id\":\"-\",\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_PleaseSelectAccount) + "\"}]"; if (string.IsNullOrEmpty(yearString) || string.IsNullOrEmpty(monthString)) { Response.Output.WriteLine(emptyResponse); Response.End(); } int year = Int32.Parse(yearString); int month = Int32.Parse(monthString); FinancialAccount account = CurrentOrganization.FinancialAccounts.AssetsBitcoinHot; if (account == null || account.OrganizationId != CurrentOrganization.Identity) { throw new UnauthorizedAccessException("All the nopes in the world"); } if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Read)) && CurrentOrganization.HasOpenLedgers) { throw new UnauthorizedAccessException("Access denied because security tokens say so"); } DateTime periodStart, periodEnd; DateTime balanceStart = Constants.DateTimeLow; bool zeroStart = false; bool zeroEnd = false; bool displayDescription = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read)); // HACK HACK HACK if (CurrentOrganization.Identity == 8 && CurrentOrganization.Name.StartsWith("Rick Falkvinge")) { // TODO displayDescription = true; // FIX THIS WITH A DAMN SETTING, YOU MORON, DON'T HARDCODE IT } bool canSeeAudit = CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Auditing, AccessType.Read)); if (month > 0 && month <= 12) { periodStart = new DateTime(year, month, 1); periodEnd = periodStart.AddMonths(1); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { balanceStart = new DateTime(year, 1, 1); if (month == 1) { zeroStart = true; } if (month == 12) { zeroEnd = true; } } } else if (month > 20 && month < 25) // quarters 1..4 are coded as months 21..24 { periodStart = new DateTime(year, (month - 21) * 3 + 1, 1); periodEnd = periodStart.AddMonths(3); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { balanceStart = new DateTime(year, 1, 1); if (month == 21) { zeroStart = true; } if (month == 24) { zeroEnd = true; } } } else if (month == 31) // "whole year" is coded as month 31 { periodStart = new DateTime(year, 1, 1); periodEnd = new DateTime(year + 1, 1, 1); if (account.AccountType == FinancialAccountType.Income || account.AccountType == FinancialAccountType.Cost) { zeroStart = true; zeroEnd = true; } } else { throw new ArgumentException("Invalid month supplied: " + month.ToString(CultureInfo.InvariantCulture)); } FinancialAccountRows rows = account.GetRows(periodStart, periodEnd); StringBuilder result = new StringBuilder(16384); Int64 runningBalance = 0L; Int64 runningBitcoinBalance = 0; string startString = Resources.Pages.Ledgers.InspectLedgers_InboundBalanceZero; string endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalanceZero; if (!zeroStart) { runningBitcoinBalance = account.GetForeignCurrencyBalanceDeltaCents(balanceStart, periodStart).Cents; runningBalance = account.GetDeltaCents(balanceStart, periodStart); startString = Resources.Pages.Ledgers.InspectLedgers_InboundBalance; } if (!zeroEnd) { endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalance; } else if (periodEnd > DateTime.Now) { // account is zeroed at end of this period, but we're not yet at end of period, so add a "to date" disclaimer endString = Resources.Pages.Ledgers.InspectLedgers_OutboundBalanceZeroToDate; } result.Append("{" + String.Format("\"description\":\"{0}\",\"balanceBitcoin\":\"{1:N2}\"", JsonSanitize(startString), runningBitcoinBalance / 100.0) + "},"); foreach (FinancialAccountRow row in rows) { string description = row.Description; if (!displayDescription) { description = Resources.Pages.Ledgers.InspectLedgers_TxDetail_DescriptionWithheld; } Int64 deltaSatoshis = row.TransactionRow.AmountForeignCents.Cents; runningBitcoinBalance += deltaSatoshis; string hasDoxString = "<img src='/Images/Icons/iconshock-search-256px.png' onmouseover=\"this.src='/Images/Icons/iconshock-search-hot-256px.png';\" onmouseout=\"this.src='/Images/Icons/iconshock-search-256px.png';\" data-txid='{0}' class='LocalIconInspect' style='cursor:pointer' height='20' width='20' />"; string actionHtml = String.Format(hasDoxString, row.FinancialTransactionId.ToString(CultureInfo.InvariantCulture)); /* * if (canSeeAudit) * { * actionHtml += * String.Format( * " <img src=\"/Images/Icons/iconshock-flag-white-16px.png\" class=\"LocalIconFlag\" txId=\"{0}\" />", * row.FinancialTransactionId.ToString(CultureInfo.InvariantCulture)); * }*/ result.Append("{" + String.Format( "\"id\":\"{0:N0}\",\"datetime\":\"{1:MMM-dd HH:mm}\",\"description\":\"{2}\"," + "\"deltaPresentation\":\"{3}\",\"deltaBitcoin\":\"{4}\",\"balanceBitcoin\":\"{5:N2}\",\"action\":\"{6}\"", row.Transaction.OrganizationSequenceId, row.TransactionDateTime, JsonSanitize(description), row.AmountCents != 0? (row.AmountCents / 100.0).ToString("N2") : string.Empty, deltaSatoshis != 0? (deltaSatoshis / 100.0).ToString("N2"): string.Empty, runningBitcoinBalance / 100.0, JsonSanitize(actionHtml)) + "},"); } if (rows.Count == 0) { // If there are no transactions in this time period, say so result.Append("{\"description\":\"" + JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_NoTransactions) + "\"},"); } result.Append("{" + String.Format("\"description\":\"{0}\",\"balanceBitcoin\":\"{1:N2}\"", JsonSanitize(endString), runningBitcoinBalance / 100.0) + "},"); Response.Output.WriteLine("[" + result.ToString().TrimEnd(',') + "]"); Response.End(); }
private void Localize() { this.LabelHeaderInspect.Text = Resources.Pages.Ledgers.InspectLedgers_Header_Inspect; this.LabelHeaderInspectFor.Text = Resources.Pages.Ledgers.InspectLedgers_Header_For; this.LabelGridHeaderAction.Text = Global.Global_Action; this.LabelGridHeaderBalance.Text = Global.Ledgers_Balance; this.LabelGridHeaderDateTime.Text = Global.Global_Timestamp; this.LabelGridHeaderDeltaNegative.Text = Global.Ledgers_Credit; this.LabelGridHeaderDeltaPositive.Text = Global.Ledgers_Debit; this.LabelGridHeaderDescription.Text = Global.Global_Description; this.LabelGridHeaderId.Text = Resources.Pages.Ledgers.InspectLedgers_TransactionId; this.LabelGridHeaderAccountName.Text = Resources.Pages.Ledgers.InspectLedgers_AccountName; this.LabelGridHeaderDateTimeEntered.Text = Resources.Pages.Ledgers.InspectLedgers_LoggedDate; this.LabelGridHeaderDeltaNegative2.Text = Global.Ledgers_Credit; this.LabelGridHeaderDeltaPositive2.Text = Global.Ledgers_Debit; this.LabelGridHeaderInitials.Text = Resources.Pages.Ledgers.InspectLedgers_LoggedByInitials; this.LabelFlagNotAvailable.Text = Resources.Pages.Ledgers.InspectLedgers_FlaggingNotAvailable; this.LabelAddTransactionRowsHeader.Text = Resources.Pages.Ledgers.InspectLedgers_HeaderAddTransactionRow; this.LabelTrackedTransactionHeader.Text = Resources.Pages.Ledgers.InspectLedgers_HeaderAutoTransactionTracking; // if write access if ( CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Write))) { LiteralEditHeader.Text = Resources.Pages.Ledgers.InspectLedgers_EditingTransactionX; this.LabelAddRowAccount.Text = Global.Financial_Account; this.LabelAddRowAmount.Text = Global.Financial_Amount; this.LiteralErrorAddRowSelectAccount.Text = Resources.Pages.Ledgers.InspectLedgers_TxDetail_ErrorAddRowNoAccount; this.LiteralAddRowButton.Text = Global.Global_Add; } else // read access, at a minimum of AccessAspect.Bookkeeping { LiteralEditHeader.Text = Resources.Pages.Ledgers.InspectLedgers_InspectingTransactionX; } // Access helpers to JavaScript (these don't actually determine access, but help in UI prettiness) this.LiteralAuditAccess.Text = (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Auditing, AccessType.Write))) ? "true" : "false"; this.LiteralWriteAccess.Text = (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Write))) ? "true" : "false"; this.LiteralDetailAccess.Text = (CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.BookkeepingDetails, AccessType.Read))) ? "true" : "false"; this.LiteralLedgersClosedUntil.Text = CurrentOrganization.Parameters.FiscalBooksClosedUntilYear.ToString(); }
protected void Page_Load(object sender, EventArgs e) { string documentIdString = Request.QueryString["DocId"]; int documentId = Int32.Parse(documentIdString); Document document = Document.FromIdentity(documentId); //Orgid is needed to safely verify permission int orgId = 0; // initialize to invalid bool hasPermission = false; switch (document.DocumentType) { case DocumentType.FinancialTransaction: { /* * //TODO: Get the orgId from foreign object * if (this.CurrentAuthority.HasPermission(Permission.CanSeeEconomyDetails, orgId, -1, Authorization.Flag.ExactOrganization)) * { * hasPermission = true; * }*/ } break; case DocumentType.ExpenseClaim: case DocumentType.InboundInvoice: { int budgetId = 0; if (document.DocumentType == DocumentType.ExpenseClaim) { ExpenseClaim claim = (ExpenseClaim)document.ForeignObject; orgId = claim.Budget.OrganizationId; budgetId = claim.BudgetId; } else { InboundInvoice invoice = (InboundInvoice)document.ForeignObject; orgId = invoice.Budget.OrganizationId; budgetId = invoice.BudgetId; } FinancialAccount budget = FinancialAccount.FromIdentity(budgetId); if (budget.OwnerPersonId == CurrentUser.Identity || budget.OwnerPersonId == 0) { hasPermission = true; break; } // TODO: Security leak - check CurrentOrganization against Document's org if ( CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Financials, AccessType.Write))) { hasPermission = true; } /* * if (this.CurrentAuthority.HasPermission(Permission.CanSeeEconomyDetails, orgId, -1, Authorization.Flag.ExactOrganization)) * { * hasPermission = true; * break; * }*/ break; } case DocumentType.PaperLetter: { PaperLetter letter = (PaperLetter)document.ForeignObject; if (letter.Recipient.Identity == CurrentUser.Identity) { hasPermission = true; // A letter to the viewer } /* * // Otherwise, are there overriding permissions, if not addressed to him/her? * * else if (!letter.Personal) * { * // Unpersonal paper letter, like a rally permit. Note that bank statements should * // be considered personal as they contain donors' information in the transaction info. * * if (this.CurrentAuthority.HasPermission(Permission.CanSeeInsensitivePaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * } * else if (letter.ToPersonId == 0) * { * // Addressed to the organization, not to a specific person, but still personal. * // Typical examples include political inquiries from private citizens written on * // paper. * * if (this.CurrentAuthority.HasPermission(Permission.CanSeeSensitivePaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * } * else * { * // Addressed to a specific individual that is not the viewer, and it's personal. * // INVOCATION OF THIS CODE IS A BREACH OF THE POSTAL SECRET and should ONLY EVER * // be done for technical, not operational, reasons and preferably NEVER. * * if (this.CurrentAuthority.HasPermission(Permission.CanBreachPostalSecretPaperLetters, letter.OrganizationId, -1, Authorization.Flag.Default)) * { * hasPermission = true; * } * }*/ } break; case DocumentType.PersonPhoto: { // These are public hasPermission = true; } break; } if (!hasPermission) { throw new Exception("Access is not allowed"); } string contentType = string.Empty; string fileNameLower = document.ClientFileName.ToLowerInvariant(); if (fileNameLower.EndsWith(".pdf")) { contentType = MediaTypeNames.Application.Pdf; } else if (fileNameLower.EndsWith(".png")) { contentType = "image/png"; // why isn't this in MediaTypeNames? } else if (fileNameLower.EndsWith(".jpg")) { contentType = MediaTypeNames.Image.Jpeg; } string legacyMarker = string.Empty; if (!File.Exists(StorageRoot + document.ServerFileName)) { legacyMarker = "legacy/"; // for some legacy installations, all older files are placed here } // TODO: If still doesn't exist, perhaps return a friendly error image instead? if (!File.Exists(StorageRoot + legacyMarker + document.ServerFileName)) { throw new FileNotFoundException(StorageRoot + legacyMarker + document.ServerFileName); } Response.ContentType = contentType + "; filename=" + document.ClientFileName; Response.TransmitFile(StorageRoot + legacyMarker + document.ServerFileName); }